Integrate file uploads into your Next.js app in minutes.
Install the SDK and React components in your Next.js project:
bun add @uploadx-sdk/core @uploadx-sdk/reactOr with npm / pnpm:
npm install @uploadx-sdk/core @uploadx-sdk/reactCreate a .env.local file with your API token and the dashboard URL. You can generate a token from the Tokens page of your app.
UPLOADX_TOKEN=upx_live_your_token_here
UPLOADX_URL=http://localhost:3000That's it — no MinIO or storage configuration needed. The SDK automatically fetches connection details from the dashboard.
A File Router declares what files your app accepts. Each route specifies file types, size limits, and what happens after upload.
import { createUploadx } from "@uploadx-sdk/core/server";
import type { FileRouter } from "@uploadx-sdk/core/server";
const f = createUploadx();
export const fileRouter = {
// Accept up to 5 images, max 4MB each
imageUploader: f({ image: { maxFileSize: "4MB", maxFileCount: 5 } })
.middleware(({ req }) => {
// Run server-side logic (auth, etc.)
// Return metadata accessible in onUploadComplete
return { userId: "user_123" };
})
.onUploadComplete(({ metadata, file }) => {
console.log("Upload by", metadata.userId, ":", file.name);
return { uploadedBy: metadata.userId };
}),
// Accept any file type up to 16MB
fileUploader: f({ blob: { maxFileSize: "16MB" } })
.onUploadComplete(({ file }) => {
console.log("File uploaded:", file.name, file.size);
}),
} satisfies FileRouter;
export type AppFileRouter = typeof fileRouter;File types: image, video, audio, pdf, text, blob (any). Size limits: "4MB", "512KB", "1GB".
Expose the file router as a Next.js API route. This handles presigned URL generation and upload completion.
import { createNextRouteHandler } from "@uploadx-sdk/core/next";
import { fileRouter } from "@/lib/uploadx";
export const { GET, POST } = createNextRouteHandler({
router: fileRouter,
});Generate type-safe upload components bound to your file router:
import { generateUploadButton, generateUploadDropzone } from "@uploadx-sdk/react";
import type { AppFileRouter } from "./uploadx";
export const UploadButton = generateUploadButton<AppFileRouter>();
export const UploadDropzone = generateUploadDropzone<AppFileRouter>();Then use them in any client component:
"use client";
import { UploadDropzone } from "@/lib/uploadx-components";
export default function Home() {
return (
<UploadDropzone
endpoint="imageUploader"
onClientUploadComplete={(files) => {
console.log("Uploaded:", files);
}}
onUploadError={(error) => {
console.error("Error:", error);
}}
/>
);
}UploadButton renders a simple button with a hidden file input. UploadDropzone renders a drag-and-drop zone with a progress bar.
For full control, use the hook directly instead of the pre-built components:
"use client";
import { useUploadX } from "@uploadx-sdk/react";
import type { AppFileRouter } from "@/lib/uploadx";
export function CustomUploader() {
const { startUpload, isUploading, progress } = useUploadX<AppFileRouter>({
endpoint: "imageUploader",
onClientUploadComplete: (files) => {
console.log("Done:", files);
},
});
return (
<div>
<input
type="file"
onChange={async (e) => {
const files = Array.from(e.target.files ?? []);
await startUpload(files);
}}
/>
{isUploading && <p>Uploading... {progress}%</p>}
</div>
);
}The hook returns: startUpload, isUploading, progress (0-100), and routeConfig (file type constraints).
Use UploadxAPI on the server to list, delete, or generate download URLs for files:
import { UploadxAPI } from "@uploadx-sdk/core/server";
// Create instance (auto-fetches config from dashboard via token)
const api = await UploadxAPI.create();
// List all files in the bucket
const files = await api.listFiles();
// Generate a signed download URL (valid 1 hour)
const url = await api.generateSignedURL("file-key", 3600);
// Delete files
await api.deleteFiles(["file-key-1", "file-key-2"]);Example: create an API route for file management in your app:
import { NextResponse } from "next/server";
import { UploadxAPI } from "@uploadx-sdk/core/server";
let api: UploadxAPI | null = null;
async function getApi() {
if (!api) api = await UploadxAPI.create();
return api;
}
export async function GET() {
const files = await (await getApi()).listFiles();
return NextResponse.json(files);
}
export async function DELETE(request: Request) {
const { keys } = await request.json();
await (await getApi()).deleteFiles(keys);
return NextResponse.json({ ok: true });
}