Quick Start
This guide gets you from zero to a working video upload UI in about 20 lines of React.
Prerequisites
- React 18+
- Packages installed (see Installation)
- A Hyperserve account (Free or Pay Per Use) and API key (for the example below)
Minimal example
Section titled “Minimal example”import { createHyperserveConfig } from "@hyperserve/upload-adapter-hyperserve";import { UploadProvider, composeValidators, maxFileSize, allowedTypes,} from "@hyperserve/upload";import { DropZone, FileList, FileListToolbar, ViewModeProvider,} from "@hyperserve/upload-react";
// These three callbacks call YOUR backend, which holds your Hyperserve API key.// The adapter handles the actual file upload to storage directly via the SDK,// but createUpload/completeUpload/getVideoStatus talk to the Hyperserve management// API, so they must be proxied server-side to keep your API key out of the browser.const config = createHyperserveConfig({ createUpload: async (file, options) => fetch("/api/create-upload", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: file.name, size: file.size, ...options }), }).then((r) => r.json()), completeUpload: async (videoId) => { await fetch(`/api/complete-upload/${videoId}`, { method: "POST" }); }, getVideoStatus: async (videoId) => fetch(`/api/video-status/${videoId}`).then((r) => r.json()), uploadOptions: { isPublic: true, resolutions: ["480p", "1080p"], }, validate: composeValidators( maxFileSize(500 * 1024 * 1024), allowedTypes(["video/*"]), ),});
function App() { return ( <UploadProvider config={config}> <ViewModeProvider> <DropZone supportingText="MP4, WebM, MOV, up to 500 MB" /> <FileListToolbar right={<FileListToolbar.ViewToggle />} /> <FileList /> </ViewModeProvider> </UploadProvider> );}What’s happening
Section titled “What’s happening”createHyperserveConfigwires up the Hyperserve adapter, status checker, and your validation rules into a single config object. The adapter callsputVideoToStoragefrom the Hyperserve SDK directly to stream the file to cloud storage; no backend is needed for that part. However,createUpload,completeUpload, andgetVideoStatusmust talk to the Hyperserve management API using your API key, which can’t be exposed in the browser. Those three callbacks are thin fetches to your own backend routes, which hold the key and proxy the calls to Hyperserve.UploadProvidermanages the upload state machine: file queue, concurrency, progress, abort/retry.ViewModeProviderprovides list/grid toggle state to the UI components.DropZonehandles drag-and-drop and file picker input.FileListrenders each file with progress bars, status badges, and action buttons.
All components read from the UploadProvider context. No prop drilling required.
Backend routes
Section titled “Backend routes”The three callbacks (createUpload, completeUpload, and getVideoStatus) must run server-side to keep your Hyperserve API key out of the browser. Each route must implement the following contract:
| Route | Receives | Returns |
|---|---|---|
POST /api/create-upload | { name: string, size: number, ...uploadOptions } | { videoId: string } |
POST /api/complete-upload/:id | (none) | 204 / empty body |
GET /api/video-status/:id | (none) | { status: string, ... } |
Try it locally
Section titled “Try it locally”git clone https://github.com/hyper-serve/uploadcd upload/examples/webcp .env.example .env # add your Hyperserve API keybun install && bun dev Next.js guide App Router example on GitHub with all three API routes.