Getting Started

Integrate file uploads into your Next.js app in minutes.

1. Installation

Install the SDK and React components in your Next.js project:

bun add @uploadx-sdk/core @uploadx-sdk/react

Or with npm / pnpm:

npm install @uploadx-sdk/core @uploadx-sdk/react

2. Environment Setup

Create a .env.local file with your API token and the dashboard URL. You can generate a token from the Tokens page of your app.

.env.local
UPLOADX_TOKEN=upx_live_your_token_here
UPLOADX_URL=http://localhost:3000

That's it — no MinIO or storage configuration needed. The SDK automatically fetches connection details from the dashboard.

3. Define a File Router

A File Router declares what files your app accepts. Each route specifies file types, size limits, and what happens after upload.

src/lib/uploadx.ts
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".

4. Create the Route Handler

Expose the file router as a Next.js API route. This handles presigned URL generation and upload completion.

src/app/api/uploadx/route.ts
import { createNextRouteHandler } from "@uploadx-sdk/core/next";
import { fileRouter } from "@/lib/uploadx";

export const { GET, POST } = createNextRouteHandler({
  router: fileRouter,
});

5. React Components

Generate type-safe upload components bound to your file router:

src/lib/uploadx-components.ts
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:

src/app/page.tsx
"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.

6. useUploadX Hook

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).

7. Server-side API

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:

src/app/api/files/route.ts
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 });
}