2

I have a Next.js app I am trying to migrate to Blitz.js.

It's a programming related site and some of the site's routes are intended to let the user run a script with something like cURL or wget piped through their shell interpreter.

These routes need to meet these two criteria:

  1. Return the response as text/plain.
  2. Read query params and adjust the data based on those params.

In Next.js I wrote middleware in pages/_middleware.js that looks like the following (and it worked). I don't understand how to port this to Blitz.js. I read the middleware page, but I don't understand where to put it in the application.

Next.js implementation

// _middleware.js
import { NextResponse, NextRequest } from 'next/server'

/**
 * This simple example just reroutes requests to /script
 * to a no-op script.
 */
export async function middleware(req, ev) {
  const { pathname } = req.nextUrl
  if (pathname == '/script') {
    let version = parseInt(req.nextUrl.searchParams.get('v'));

    if (isNaN(version)) {
      version = 'latest';
    }   
    
    const params = !version ? '' : `?version=${version}`;
    return NextResponse.rewrite(`/api/basic-script${params}`);
  }
  return NextResponse.next();
}
// pages/api/basic-script.js
export default function handler (req, res) {
  let {version} = req.query;
  version = parseInt(version);

  if (isNaN(version)) {
    version = latest;
  }

  res.status(200).send(
    'echo "This script doesn't do anything yet. (version: ${version})"
  );
}

Blitz.js implementation

Adding the API endpoint works as expected, but I don't know where to put the middleware (or how to write it in Blitz).

It looks to me like adding a middleware property to the config in blitz.config.js isn't the right solution to this, since that would just redirect me to a new page.

I tried adding the same _middleware.js file in Blitz's app/pages/, but it didn't seem to be loading.

Sir Robert
  • 4,686
  • 7
  • 41
  • 57

1 Answers1

0

I had the same issue and was able to resolve with the following:

// blitz.config.ts
import { BlitzConfig, connectMiddleware } from "blitz"
import middlewareHandler from "app/pages/middleware" // your middleware file

const config: BlitzConfig = {
  middleware: [
    connectMiddleware(middlewareHandler),
  ],
}

module.exports = config
// app/pages/middleware.ts
import { BlitzApiRequest, BlitzApiResponse } from "blitz"
import Cors from "cors"

// Initializing the cors middleware
const cors = Cors({
  methods: ["GET", "POST", "HEAD", "OPTIONS"],
})

// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result) => {
      if (result instanceof Error) {
        return reject(result)
      }

      return resolve(result)
    })
  })
}

async function handler(req: BlitzApiRequest, res: BlitzApiResponse) {
  // Run the middleware
  return await runMiddleware(req, res, cors)
}

export default handler
John
  • 101
  • 5