How To Access Raw Body Data with Next.js

February 13, 2023

Sometimes with a Next.js API endpoint, you need to parse the raw body data your own way. I came across this need when writing handlers for LemonSqueezy and Paddle webhooks to automate things after payments and cancellations happen.

Define Your API Endpoint Route

This is a minimal working example of an API endpoint route for Next.js that will get the raw request body for payload signature verification and also parse it into JSON for your own implementation uses.

TypeScript
// File: `pages/api/webhooks/someProvider.ts`

import type { NextApiRequest, NextApiResponse } from 'next';
import type { Readable } from 'node:stream';

// EXPORT config to tell Next.js NOT to parse the body
export const config = {
  api: {
    bodyParser: false,
  },
};

// Get raw body as string
async function getRawBody(readable: Readable): Promise<Buffer> {
  const chunks = [];
  for await (const chunk of readable) {
    chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);
  }
  return Buffer.concat(chunks);
}

// API handler function
export default async function handler(req: NextApiRequest, res: NextApiResponse<any>) {
  const rawBody = await getRawBody(req);
  console.log('raw body for this request is:', rawBody);

  const data = JSON.parse(Buffer.from(rawBody).toString('utf8'));
  console.log('json data for this request is:', data);

  res.send('Got raw body!');
}

Parse a Raw Body Into JSON

If you want to turn the raw body into parsable JSON yourself, you can do that with this one-liner:

TypeScript
const data = JSON.parse(Buffer.from(rawBody).toString('utf8'));

This code is included in the example code above. This is handy if you need to use both a custom parser or payload verification on the raw body, but still also need to use the body content as JSON data.

Implement Your Own Handler

Now you are free to implement your own code to handle the webhook or API request however you want inside the handler method that is default exported. This is the same base code that is in BudgetSheet running in production handling hundreds of payments and webhook requests. It works great! Good luck on your own implementation! 😊


Tags: , , ,

Categories: ,