Documentation menu

Next.js Quickstart

@upupjs/next is the Next.js integration for upup: one install gives you the client UI and the server handlers, split across two entry points so the AWS SDK never reaches your client bundle. The client entry re-exports the full @upupjs/react UI; the /server entry provides App Router and Pages Router handlers.

Requires Next.js 15+ and React 19 (next, react, and react-dom are peer dependencies).

Install

sh
npm i @upupjs/next

Client component

@upupjs/next re-exports @upupjs/react, so UpupUploader (and its hooks, icons, and theme provider) come straight from @upupjs/next. Render it in a client component:

tsx
'use client'

import { UpupUploader } from '@upupjs/next'
import '@upupjs/next/styles'

export default function Uploader() {
    return <UpupUploader provider="aws" uploadEndpoint="/api/upload-token" />
}

That's client mode — the browser uploads directly to your storage and needs no server package. To proxy uploads and cloud drives through your own server, point the same component at the handler below:

tsx
<UpupUploader mode="server" serverUrl="/api/upup" />

Server — App Router

Create a catch-all route at app/api/upup/[...path]/route.ts. createUpupNextHandler returns the HTTP method handlers; defineUpupConfig gives you typed config.

ts
import { createUpupNextHandler, defineUpupConfig } from '@upupjs/next/server'

export const dynamic = 'force-dynamic'
export const maxDuration = 60

export const { GET, POST, PUT, DELETE } = createUpupNextHandler(
    defineUpupConfig({
        storage: {
            type: 'aws',
            bucket: process.env.S3_BUCKET!,
            region: process.env.S3_REGION!,
        },
        // REQUIRED — HMAC-signs upload tokens. Must be >= 16 chars and identical
        // on every instance; the handler THROWS at construction time without it.
        uploadTokenSecret: process.env.UPUP_UPLOAD_TOKEN_SECRET,
    }),
)

Add serverExternalPackages: ['@aws-sdk/client-s3', '@aws-sdk/s3-request-presigner'] to your next.config so the AWS SDK is bundled as a server external.

Server — Pages Router

A Pages Router adapter ships too: createUpupPagesHandler, used as the route file's default export at pages/api/upup/[...path].ts, with export const config = { api: { bodyParser: false } } so the handler can read the raw body. Same required uploadTokenSecret rule applies. See Server Mode — Setup for the full walkthrough — auth and user binding, production token stores, and serverless notes (persist the TokenStore, raise maxDuration for large transfers).

What you get

  • Cloud drives — Google Drive, OneDrive, Dropbox, and Box, browsed in-panel.
  • Camera and screen capture sources.
  • Link import — add files by URL.
  • Resumable uploads — optional tus or S3 multipart for large files.
  • Image editor — crop, rotate, and annotate (React and Preact only).
  • ICU i18n — locale bundles with pluralization and per-key overrides.
  • Theming — design tokens, slots, and dark mode via UpupThemeProvider.

Also exported

From @upupjs/next: the full @upupjs/react surface (UpupUploader, UpupThemeProvider, the brand source icons, and the use* hooks). From @upupjs/next/server: createUpupNextHandler, createUpupPagesHandler, defineUpupConfig, and InMemoryTokenStore (dev-only — bring your own TokenStore in production).

Try it live in the playground

Tweak every prop and see the uploader respond instantly.