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/reactnpm install @uploadkitdev/next @uploadkitdev/reactyarn add @uploadkitdev/next @uploadkitdev/reactCreate your file router
Create app/api/uploadkit/[...uploadkit]/route.ts and define which files your app accepts:
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:
UPLOADKIT_API_KEY=uk_live_xxxxxxxxxxxxxxxxxxxxxUPLOADKIT_API_KEY— server-side only; used by your file router handler to authenticate with the UploadKit API. Never prefix withNEXT_PUBLIC_.
Add the provider
Wrap your root layout's children with UploadKitProvider, pointing it at the route handler you created in the previous step:
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:
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
- Next.js App Router guide — full setup with multiple routes, middleware, and type-safe helpers
- React / Vite guide — for non-Next.js React apps
- API Only guide — for any language via REST API
- Theming — customize colors, radius, and dark mode
- Bring Your Own Storage — use your own S3 or R2 bucket