Skip to content

Quick Start — Next.js

Terminal window
npm install @queuebase/nextjs zod

Zod is used in this guide, but Queuebase supports any Standard Schema-compatible validation library (Valibot, ArkType, etc.). The CLI runs via npx — no separate install needed.

Create a job router with validated inputs:

src/jobs/index.ts
import { createJobRouter, job } from "@queuebase/nextjs";
import { z } from "zod";
export const jobs = createJobRouter({
sendEmail: job({
input: z.object({
to: z.string().email(),
subject: z.string(),
body: z.string(),
}),
handler: async ({ input, jobId, attempt }) => {
console.info(`[job ${jobId}] Sending email to ${input.to} (attempt ${attempt})`);
// your email sending logic here
return { sent: true };
},
defaults: {
retries: 3,
backoff: "exponential",
},
}),
});
export type JobRouter = typeof jobs;

The handler receives a context object with:

  • input — the validated payload (typed from your schema)
  • jobId — unique identifier for this job execution
  • attempt / maxAttempts — retry tracking (attempts are 1-indexed)
  • fail(reason) — explicitly mark the job as failed

See Defining Jobs for more options.

The client gives you a type-safe way to enqueue jobs:

src/jobs/client.ts
import { createClient } from "@queuebase/nextjs";
import { jobs } from "./index";
export const jobClient = createClient(jobs, {
apiUrl: process.env.QUEUEBASE_API_URL ?? "http://localhost:3847",
apiKey: process.env.QUEUEBASE_API_KEY,
callbackUrl:
process.env.QUEUEBASE_CALLBACK_URL ??
"http://localhost:3000/api/queuebase",
});
  • apiUrl — where the Queuebase API lives. In development, this is the CLI dev server (http://localhost:3847). In production, it’s your hosted Queuebase API.
  • apiKey — authenticates with the production API. Not needed during local development.
  • callbackUrl — the URL Queuebase POSTs to when it’s time to execute a job. This points to the webhook handler you’ll create next.

This is the endpoint Queuebase calls to execute your jobs:

src/app/api/queuebase/route.ts
import { createHandler } from "@queuebase/nextjs/handler";
import { jobs } from "@/jobs";
export const POST = createHandler(jobs);

If you’re using the Pages Router instead of the App Router, use createPagesHandler from @queuebase/nextjs/pages. You must disable the built-in body parser so Queuebase can verify webhook signatures against the raw request body:

pages/api/queuebase.ts
import { createPagesHandler } from "@queuebase/nextjs/pages";
import { jobs } from "@/jobs";
export const config = { api: { bodyParser: false } };
export default createPagesHandler(jobs);

Call .enqueue() from a server action, route handler, or anywhere server-side:

src/app/actions.ts
"use server";
import { jobClient } from "@/jobs/client";
export async function sendWelcomeEmail(to: string) {
const { jobId } = await jobClient.sendEmail.enqueue({
to,
subject: "Welcome",
body: "Hello!",
});
return jobId;
}

When you call .enqueue(), the SDK validates the input against your schema, sends the job to the Queuebase API, and returns a jobId you can use to check status later. The worker picks up the job and POSTs back to your webhook handler to execute it.

In one terminal, start the Queuebase dev server:

Terminal window
npx queuebase dev

In another terminal, start your Next.js app:

Terminal window
npm run dev

The Queuebase dev server starts on port 3847, stores jobs in a local SQLite database, and polls for pending jobs to execute.

What you should see: Trigger the enqueue from your app. The Queuebase CLI should log the job being received and executed. If you added the console.info in step 2, you’ll see the log output in the Next.js terminal where your handler runs.