Astro File Upload

Upload Files from Astro API Routes with fetch

Upload files from Astro API routes with fetch. No SDK, REST API, CDN delivery, prepaid credits.

Astro is static-first, but its API endpoints (src/pages/api/*.ts exporting POST) and on-demand server routes give you a place to run server code — which is exactly what a secure file upload needs. files.link plugs into an Astro endpoint with three fetch calls: no aws-sdk, no adapter-specific storage binding, and the same code works whether you deploy with the Node, Vercel, Netlify, or Cloudflare adapter.

The Astro-specific gotcha is environment variables. Astro exposes anything prefixed PUBLIC_ to the client bundle, so your API key must be referenced as a server-only variable (import.meta.env.FILESLINK_KEY with no PUBLIC_ prefix) and used only inside the endpoint, never in a .astro component's frontmatter that gets serialized.

ts
// src/pages/api/upload.ts
import type { APIRoute } from 'astro';

export const POST: APIRoute = async ({ request }) => {
  const form = await request.formData();
  const file = form.get('upload') as File;
  const key = import.meta.env.FILESLINK_KEY;

  const r1 = await fetch(`https://api.files.link/v1/files/${import.meta.env.FOLDER_ID}`, {
    method: 'POST',
    headers: { Authorization: key, 'Content-Type': 'application/json' },
    body: JSON.stringify({ filesMetadata: [{ name: file.name, size: file.size, type: file.type }] }),
  });
  const slot = (await r1.json()).urls[0];

  await fetch(slot.url, { method: 'PUT', body: file });

  await fetch('https://api.files.link/v1/files/confirm-upload', {
    method: 'POST',
    headers: { Authorization: key, 'Content-Type': 'application/json' },
    body: JSON.stringify({ ids: [slot.id] }),
  });
  return new Response(JSON.stringify({ id: slot.id }), {
    headers: { 'Content-Type': 'application/json' },
  });
};

The powerful part for an Astro project is hybrid rendering: keep your site output: 'static' for speed and SEO, but mark the upload endpoint as prerender = false so only that route runs on-demand server-side. You get a fully static marketing or docs site plus a real upload backend, without splitting into two deployments. The CDN URL you get back drops straight into an <img> or <video> tag rendered at build or request time.

The Authorization header takes the raw key, files come back as CDN URLs with per-file visibility, storage is encrypted at rest, and billing is prepaid credits with no metered egress invoice.

Benefits With No Complexity

Global CDN delivery

Your files are served from 450+ edge locations worldwide.

Edge-cached worldwide

Files are cached close to your users for fast delivery.

Signed-URL security

Private files stay protected with time-limited access.

What You Get

Unlimited files

Upload as many files as you need.

Unlimited storage

There is no storage limit.

Public + Private storage

Private files are fully secured.

CDN ready links

Upload directly to 450+ edge locations worldwide.

Prepaid credits

No subscription. Pay only for the storage and bandwidth you use.

More coming soon

We have plenty of features coming!

How files.link Works

1. Upload

Create a project and upload your first file.

2. Copy

Copy the CDN link.

3. Use Anywhere

Paste and enjoy the blazing speed.

Why Developers Choose files.link

A Better Way to Store & Deliver Files

AWS S3 (aws-sdk)Netlify Blobsfiles.link
Works in Astro API routes (no SDK)
Same code across all SSR adapters
Hybrid static + on-demand endpoint
Global CDN delivery on every file
Prepaid credits (no surprise bills)

Calculate Your Needs

Storage

0GB

Egress

0GB

CDN Bandwidth

0GB
Total: $0.000/month

Wire Up Astro File Uploads

  • Global CDN delivery
  • Edge-cached worldwide
  • Signed-URL security
  • Unlimited files
  • Unlimited storage
  • Public + Private storage
  • No subscription — prepaid credits keep spend predictable
Start Uploading from Astro

Frequently Asked Questions

How do I keep the API key out of the client in Astro?
Reference it as import.meta.env.FILESLINK_KEY without a PUBLIC_ prefix and use it only inside the API endpoint. Astro only ships PUBLIC_-prefixed vars to the browser, so a server-only var stays server-only.
Can my site stay static and still have uploads?
Yes. Keep output: 'static' for the site and set prerender = false on just the upload endpoint. That single route runs on-demand server-side while the rest of the site is fully static.
Does this work with the Cloudflare or Vercel adapter?
Yes. The three calls are plain fetch, which every Astro SSR adapter supports. You don't change the upload code when you switch between Node, Vercel, Netlify, or Cloudflare adapters.
How do I render the uploaded file?
After confirm-upload you get a CDN URL. Drop it into an <img src> or <video src> in your .astro template. Public files resolve over the global CDN; private files use short-lived signed URLs.
Do I need any storage SDK?
No. There is no aws-sdk or adapter-specific storage binding to install — just the built-in fetch and three REST calls to files.link.
General Questions
Is there a subscription?
No. files.link uses prepaid credits, so storage, bandwidth, and API usage are deducted from your balance as you go. The app explains the payment step before uploads are enabled — no monthly subscription and no per-user fees.
What is files.link?
files.link is a developer-first file platform that makes it simple to store, secure, and deliver files globally. It provides signed URLs, public/private access, and an API-first design so you can integrate file delivery into any app without the usual complexity.
How does billing work?
files.link uses prepaid credits. As you use storage, bandwidth, and API requests, credits are deducted daily. When your balance runs low, we automatically recharge it using your saved card. If an auto-recharge doesn't go through, your files and links stay put — you simply update your payment method or top up manually to keep going. No monthly subscriptions — just simple usage-based pricing.
How secure is my data?
All files are encrypted at rest and in transit. You can use signed URLs for private files, control access with permissions, and rely on enterprise-grade infrastructure for data protection.

Related

files.link
Copyright © 2026
All rights reserved
ContactGuidesGlossaryStatusLegal