Installation
Add @uploadkitdev/next and @uploadkitdev/react to your Next.js app.
@uploadkitdev/next provides the server-side route handler for Next.js App Router. Pair it with @uploadkitdev/react for the client-side UI components.
Install packages
pnpm add @uploadkitdev/next @uploadkitdev/reactnpm install @uploadkitdev/next @uploadkitdev/reactyarn add @uploadkitdev/next @uploadkitdev/reactSet environment variables
Add your UploadKit API key to .env.local. Only one variable is needed — the key lives on the server only.
UPLOADKIT_API_KEY=uk_live_xxxxxxxxxxxxxxxxxxxxxGet your API key from dashboard.uploadkit.dev. Never prefix this with NEXT_PUBLIC_ — the key is used only by the server-side route handler, never by client components.
Create the file router
Create app/api/uploadkit/[...uploadkit]/route.ts and define your routes:
import { createUploadKitHandler } from '@uploadkitdev/next';
import type { FileRouter } from '@uploadkitdev/next';
const fileRouter = {
imageUploader: {
maxFileSize: '4MB',
allowedTypes: ['image/*'],
onUploadComplete: async ({ file, metadata }) => {
console.log('Uploaded:', file.url);
},
},
} satisfies FileRouter;
export type AppFileRouter = typeof fileRouter;
export const { GET, POST } = createUploadKitHandler({
router: fileRouter,
apiKey: process.env.UPLOADKIT_API_KEY,
});Using satisfies FileRouter (not a type annotation) preserves the literal route name keys. This is required for the client components to be fully type-safe.
Wrap your app with UploadKitProvider
In your root layout, add UploadKitProvider pointing at the route handler you just created. Browser components call /api/uploadkit — your API key stays on the server:
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
import { UploadButton } from '@uploadkitdev/react';
export default function Page() {
return (
<UploadButton
route="imageUploader"
onUploadComplete={(result) => console.log('Done:', result.url)}
/>
);
}Next steps
- File router — full
RouteConfigoptions with multiple routes - Middleware — extract auth context and reject uploads
- Type safety — typed components with
generateReactHelpers - API reference — complete type definitions