Source Code

This is a step by step guide on how to receive webhooks from qstash in your Next.js app.

1

Create a new nextjs app named `qstash-receiver`

There are great tutorials on how to setup Next.js on Vercel, so I won’t go into details here.

npx create-next-app qstash-receiver
cd qstash-receiver
2

Install qstash

npm install @upstash/qstash@latest
3

Write your function

/pages/api/qstash-serverless.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { verifySignature } from "@upstash/qstash/dist/nextjs";

async function handler(req: NextApiRequest, res: NextApiResponse) {
  console.log(req.headers);

  await new Promise((r) => setTimeout(r, 1000));

  console.log("Success");
  console.log(typeof req.body, { body: req.body });
  res.status(200).json({ name: "John Doe", body: req.body });
}

export default verifySignature(handler);

export const config = {
  api: {
    bodyParser: false,
  },
};

verifySignature or verifySignatureEdge will try to load QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY from the environment. If one of them is missing, an error is thrown. We will set these in step 5.

4

Deploy to Vercel

I’m deploying using Vercel’s CLI, but you could also push your project to a remote repo and deploy that way. If you have never used the cli, please run npx vercel login before. See here

You can accept all the default settings.

$ npx vercel

Vercel CLI 24.2.5
? Set up and deploy “~/github/upstash/qstash-examples/vercel-nextjs”? [Y/n] y
? Which scope do you want to deploy to? Andreas Thomas
? Link to existing project? [y/N] n
? What’s your project’s name? vercel-nextjs
? In which directory is your code located? ./
Auto-detected Project Settings (Next.js):
- Build Command: next build
- Output Directory: Next.js default
- Development Command: next dev --port $PORT
? Want to override the settings? [y/N] n
🔗  Linked to chronark/vercel-nextjs (created .vercel)
🔍  Inspect: https://vercel.com/chronark/vercel-nextjs/FZScmeKCWr5snn6P8voyv3W28npf [904ms]
✅  Production: https://vercel-nextjs-two-sandy.vercel.app [copied to clipboard] [37s]
📝  Deployed to production. Run `vercel --prod` to overwrite later (https://vercel.link/2F).
💡  To change the domain or build command, go to https://vercel.com/chronark/vercel-nextjs/settings
5

Set Signing Keys in Vercel

Go to your project’s settings and set the following environment variables:

6

Redeploy to use the new environment variables

To make the added environment variables take effect, you must redeploy your project.

$ npx vercel --prod
Vercel CLI 24.2.5
🔍  Inspect: https://vercel.com/chronark/vercel-nextjs/3wPxyEPwdcMrncSNqFNcDD41rjxB [3s]
✅  Production: https://vercel-nextjs-two-sandy.vercel.app [copied to clipboard] [39s]
7

Publish a message

Go to your project’s logs and then publish a new message.

curl --request POST "https://qstash.upstash.io/v2/publish/https://vercel-nextjs-two-sandy.vercel.app/api/qstash" \
     -H "Authorization: Bearer <QSTASH_TOKEN>" \
     -H "Content-Type: application/json" \
     -d "{ \"hello\": \"world\"}"
{"messageId":"msg_5GJrFa5aMFxDYsDygAnW9YW8cmRm"}

In the logs you should see something like this:

[POST] /api/qstash
If this is printed, the signature has already been verified

That’s it, you have successfully created a secure Next.js API route, that receives and verifies incoming webhooks from qstash.

Learn more about publishing a message to qstash here