Next.js File Upload

Upload Files from Next.js Route Handlers and Server Actions

Upload files from Next.js route handlers or server actions. No SDK, REST API, CDN delivery.

Next.js gives you two clean server-side seams for file uploads — Route Handlers (app/api/.../route.ts) and Server Actions — and both can talk to files.link with the built-in fetch, no SDK. The advantage over Vercel Blob is that you are not married to one host: the same code runs on Vercel, Netlify, Railway, a container on CapRover, or a self-hosted Node server. The advantage over wiring up aws-sdk is that there is no IAM user, no bucket policy, and no SigV4 signing — just three fetch calls and an env var.

The non-negotiable rule: keep the API key server-side. It must never appear in a Client Component, a 'use client' file, or any NEXT_PUBLIC_ variable, or it ends up in the browser bundle. Route Handlers and Server Actions run only on the server, so process.env.FILESLINK_KEY stays safe there.

A Route Handler that proxies the upload:

ts
// app/api/upload/route.ts
export async function POST(req: Request) {
  const form = await req.formData();
  const file = form.get('file') as File;
  const key = process.env.FILESLINK_KEY!;

  const r1 = await fetch(`https://api.files.link/v1/files/${process.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 { urls } = await r1.json();
  const slot = 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 Response.json({ id: slot.id });
}

The identical three-call sequence works inside a Server Action — mark the function 'use server', accept the FormData, and return the CDN URL to revalidate your UI. For very large files you can skip proxying the bytes through your server entirely: return the presigned PUT URL to the browser and let the client PUT directly to it, then call confirm-upload server-side.

That offloads bandwidth from your Vercel function and keeps you under serverless body-size limits. Files come back as CDN URLs, visibility is per file, storage is encrypted at rest, and billing is prepaid credits. For copy-paste code covering all three approaches, see the full step-by-step Next.js upload tutorial.

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

Vercel BlobAWS S3 (aws-sdk)files.link
Runs on any host (not Vercel-locked)
No SDK — just built-in fetch
Direct browser→storage upload option
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 Next.js 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 Next.js

Frequently Asked Questions

Route Handler or Server Action — which should I use?
Use a Route Handler when you want a stable POST endpoint that a client fetch or external caller hits. Use a Server Action when the upload is driven by a form inside your React component tree. Both run server-side and use the same three-call flow.
How do I keep the API key out of the browser bundle?
Reference it only as process.env.FILESLINK_KEY inside server code (Route Handlers, Server Actions). Never use a NEXT_PUBLIC_ prefix for it and never read it from a 'use client' component, or it gets inlined into the client bundle.
Can I avoid proxying large files through my serverless function?
Yes. Return the presigned PUT URL to the browser and let the client PUT the bytes directly to it. Your function only handles the small metadata POST and the confirm POST, keeping you under serverless body-size limits.
Does this work with the Edge runtime?
The metadata and confirm calls are plain fetch and work on Edge. For proxying large request bodies, the Node runtime is safer because of Edge body-size and CPU limits — or use the direct browser-upload pattern.
How do I revalidate the UI after upload?
From a Server Action, call revalidatePath or revalidateTag after confirm-upload returns. The new CDN URL then renders on the next request without a full reload.
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