UploadKit
Getting Started

Quickstart

Get file uploads working in your Next.js app in under 5 minutes.

Need an API key? Create a free account at dashboard.uploadkit.dev to get one.

Install packages

Add @uploadkitdev/next (server-side handler) and @uploadkitdev/react (UI components) to your project:

pnpm add @uploadkitdev/next @uploadkitdev/react
npm install @uploadkitdev/next @uploadkitdev/react
yarn add @uploadkitdev/next @uploadkitdev/react

Create your file router

Create app/api/uploadkit/[...uploadkit]/route.ts and define which files your app accepts:

app/api/uploadkit/[...uploadkit]/route.ts
import { createUploadKitHandler } from '@uploadkitdev/next';
import type { FileRouter } from '@uploadkitdev/next';

const router = {
  imageUploader: {
    maxFileSize: '4MB',
    allowedTypes: ['image/*'],
    onUploadComplete: async ({ file, metadata }) => {
      // Save file info to your database
      console.log('Upload complete:', file.url);
    },
  },
} satisfies FileRouter;

export const { GET, POST } = createUploadKitHandler({ router });

Using satisfies FileRouter (not a type annotation) preserves the literal route names — this is what makes the client components fully type-safe.

Set environment variables

Add your API key to .env.local:

.env.local
UPLOADKIT_API_KEY=uk_live_xxxxxxxxxxxxxxxxxxxxx
  • UPLOADKIT_API_KEY — server-side only; used by your file router handler to authenticate with the UploadKit API. Never prefix with NEXT_PUBLIC_.

Add the provider

Wrap your root layout's children with UploadKitProvider, pointing it at the route handler you created in the previous step:

app/layout.tsx
import { UploadKitProvider } from '@uploadkitdev/react';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <UploadKitProvider endpoint="/api/uploadkit">
          {children}
        </UploadKitProvider>
      </body>
    </html>
  );
}

Add an upload component

Drop <UploadDropzone> into any page and point it at your file route:

app/page.tsx
import { UploadDropzone } from '@uploadkitdev/react';

export default function Page() {
  return (
    <main>
      <h1>Upload an image</h1>
      <UploadDropzone
        route="imageUploader"
        onUploadComplete={(files) => {
          console.log('Uploaded:', files);
        }}
      />
    </main>
  );
}

That's it! You now have a working file upload with type validation, size limits, and direct-to-storage uploads via presigned URLs — no server bottleneck.

Next steps

On this page