Skip to main content

Prerequisites

  • Node.js 18+
  • A SyncSnap project and API key from the dashboard (or your backend that creates jobs and returns download URLs)
  • Next.js app using the App Router

Step 1: Install packages

npm install @syncsnap/react syncsnap
Peer dependencies for the React components (Tailwind and React):
npm install react tailwindcss

Step 2: Environment variable

Your server needs the SyncSnap API key. In .env.local:
SYNCSNAP_TOKEN=your_api_key_here
Never expose this key to the browser; only the server SDK should use it.

Step 3: API route

Create the SyncSnap API route so the frontend can create jobs and wait for completion (and optionally get download URLs). Create this file: app/api/syncsnap/[...syncsnap]/route.ts
import { SyncsnapServer } from "syncsnap";
import { createRouteHandler } from "syncsnap/next";

const client = new SyncsnapServer();

export const { GET, POST } = createRouteHandler({
  client,
  onCompleted: async (job, presigned) => {
    // Optional: run when job completes. Return value is sent to the client as onCompleted(job, result).
    return presigned ? { downloadUrl: presigned.url, fileName: presigned.fileName } : undefined;
  },
});
This single catch-all route handles:
  • POST /api/syncsnap/job — create job
  • GET /api/syncsnap/job/:id — get job
  • GET /api/syncsnap/job/:id/wait — server waits until job completes, then returns { job, result? } (result is from your onCompleted callback or the presigned URL)
  • GET /api/syncsnap/job/:id/download — get presigned download URL

Step 4: Add the upload button

In any client component:
"use client";

import { SyncsnapUploadButton } from "@syncsnap/react";

export default function Page() {
	return (
		<SyncsnapUploadButton
			buttonText="Scan to upload"
			onCompleted={(job, result) => {
				// result is whatever your server onCompleted returned (e.g. { downloadUrl, fileName })
				if (result && typeof result === "object" && "downloadUrl" in result)
					console.log("Download URL:", (result as { downloadUrl: string }).downloadUrl);
			}}
		/>
	);
}

Step 5: Styles (Tailwind)

The button and dialog use Tailwind and the SDK theme. In your main CSS (e.g. app/globals.css):
@import "tailwindcss";
@import "@syncsnap/react/theme";
If you use Tailwind v3 or a different setup, see Styling.

Step 6: Run and test

  1. Start the dev server: npm run dev
  2. Open the page and click Scan to upload.
  3. A dialog opens with a QR code. Scan it with your phone and upload a file.
  4. When the job completes, onCompleted runs and you can use the presigned download URL.

Optional: QR code base URL

If the default upload host is wrong (e.g. local or staging), set where the QR code should point:
<SyncsnapUploadButton
	buttonText="Scan to upload"
	qrBaseUrl="https://upload.staging.syncsnap.xyz"
/>
Next: Next.js App Router for a fuller walkthrough, or React SDK and Server SDK for all options.