vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.11k stars 26.88k forks source link

Docs: clarify how top level variables will work for middleware #68626

Closed jeroenheijmans closed 2 months ago

jeroenheijmans commented 2 months ago

What is the update you wish to see?

I would like to see some documentation that helps me understand how a top level variable (e.g. let counter = 0;) can be expected to function in middleware. Can we expect the state to be persisted across requests? And if so: for which environments/runtimes?

Background

I'm trying to follow the "Redirects at Scale" documentation. In my case the redirects settings will come from a headless CMS, managed by content managers. My production app will be a standalone build running in Azure as a web app.

For this moment I considered omitting a full key-value store like Redis for a cache, and decided I'd try to see if an in-memory cache would be good enough. I made an assumption that a global singleton variable would work well enough in middleware (realizing that if my app scales to multiple instances each will have its own cache), and wanted to test this.

Reproducible scenario

To test things, I created the most minimal reproducible scenario I could think of:

import type { NextRequest } from "next/server";

let counter = 0;

export async function middleware(request: NextRequest) {
  if (request.nextUrl.pathname === "/") console.log(`---- Middleware counter: ${++counter}`);
}

export const config = {
  matcher: [ "/((?!api|_next/static|_next/image|favicon.ico|assets).*)" ],
};

Results

Different situations give me different results when running locally:

My main surprise here was the difference between minor 13.x versions. This difference in behavior seems like a potential breaking change?

In all cases I used the Pages router.

What have I tried?

Before opening this issue I've tried to answer my own questions by thoroughly searching, amongst others:

I could not find any documentation on the expected behavior of my code.

Bottom line

I want to know how a "global" variable is supposed to behave in NextJS middleware, and would like to see some documentation that explains this. I don't mind much what the location of these docs is.

Although I'd be happy to have the 14.2.5 style behavior with persisted state across requests for dev and standalone node-hosted builds, I'm mostly looking to know what the behavior should be. Currently I'm afraid the behavior I see is not guaranteed and prone to be changed back in another minor or major release.

Does the docs page already exist? Please link to it.

https://nextjs.org/docs/pages/building-your-application/routing/middleware

samcx commented 2 months ago

@jeroenheijmans Thanks for sharing this docs request!

Sorry if it wasn't clear enough, but any "docs requests" should be this template. I'll try to make this clearer! I'll be moving this to discussions in the meantime.

CleanShot 2024-08-08 at 14 05 39@2x