Skip to content

global object is not the same in middleware and route. #56918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
aszx87410 opened this issue Oct 17, 2023 · 9 comments
Closed
1 task done

global object is not the same in middleware and route. #56918

aszx87410 opened this issue Oct 17, 2023 · 9 comments
Labels
bug Issue was opened via the bug report template. stale The issue has not seen recent activity.

Comments

@aszx87410
Copy link

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/focused-forest-j2z84n

To Reproduce

  1. Start the application
  2. Visit http://localhost:3000
  3. Observe [middleware] global.test123 test123 set in the console log.
  4. Visit http://localhost:3000/testRoute or click the link in the index page.
  5. Observe [route] global.test123 undefined in the log.

Current vs. Expected behavior

The application is quite simple, only two files involved.

In the middleware, global.test123 has be set to a string:

import { NextResponse } from 'next/server';

export function middleware(request) {
 global.test123 = 'test123 set'
 console.log('[middleware] global.test123', global.test123)
 return NextResponse.next();
}

And in the testRoute/route.js, the value of global.test123 is printed.

export async function GET(request) {  
    console.log('[route] global.test123', global.test123);

    return new Response('ok', {
        status: 200,
        headers: {
          'Content-Type': 'text/html; charset=utf-8',
        },
      });
}

Expected result

Since both middleware and route only runs in the server, I expect the global object in the middleware and the route are the same object, so global.test123 should be a string in the route handler.

Actual result

global.test123 is undefined is the route handler.

截圖 2023-10-17 13 49 51

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
Binaries:
  Node: 20.5.1
  npm: 9.8.0
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 13.5.6-canary.1
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: N/A
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

App Router

Additional context

No response

@aszx87410 aszx87410 added the bug Issue was opened via the bug report template. label Oct 17, 2023
@icyJoseph
Copy link
Contributor

icyJoseph commented Oct 17, 2023

Mmm I think, somewhat counter intuitively perhaps, that this is to be expected?

If we think of "by the book" deploy, the middleware, might not even run in the same computer as the rest of the server.

More over, it runs using the edge runtime.

In Next.js there are 2 server side runtimes, nodejs, and edge.

Now, I guess, there might be an expectation to, when running local dev, or hosting things oneself, to have everything in the same runtime, but that's not the case.

I am not sure there's any guarantees either, because, you could try to export export const runtime = 'edge' on your Route handler, but at deploy time, the middleware and route handler might not even be on the same computer.

During dev time, also I guess a Worker compiles the route, and might share different environment contexts with the function execution.

@aszx87410
Copy link
Author

I can understand that in cases with an edge, middleware might be separate components. However, if an edge is not required, should all components run in the same process? Otherwise, it does indeed seem a bit counterintuitive, especially when running a single server, as one naturally assumes that everything operates under the same global context.

Furthermore, if middleware must run in a different context from other components, does it imply that data sharing between them is not possible? (Excluding workarounds like storing data in a database.) I'm not sure if Next.js has a solution for this aspect.

Regarding the export const runtime = 'edge', I tried in both dev and production build, does not work, still two different contexts.

@dengBox

This comment has been minimized.

@ekwoka
Copy link

ekwoka commented Nov 22, 2023

You're not actually supposed to mutate the global object like this.

The way Next works, the middle wares and routes can all be in different threads.

That's why each has to accept a request and return a response.

If you need middle ware to provide info to handlers, you would need to actually put them on the response object, presumable in headers to preserve them.

@aszx87410
Copy link
Author

@ekwoka I can totally understand if the middleware is in a different thread. I just curious where did you get this knowledge from? Is there any documentation about this behavior (middleware and routes can be different threads)? Would be great if you can shed the light on it, thanks!

@ekwoka
Copy link

ekwoka commented Nov 22, 2023

The documentation is poor. You mostly need to look at the source to see how this works.

The thing that clued it in for me was that you call a global next

If middleware can be async, and you call a global next then it suggests that calling next does not ACTUALLY call the next thing, but has a controller manage it all. Likely because of multithreading.

@dengBox
Copy link

dengBox commented Nov 22, 2023

Maybe you can try doing this
image
image
image

@nextjs-bot
Copy link
Collaborator

This issue has been automatically marked as stale due to two years of inactivity. It will be closed in 7 days unless there’s further input. If you believe this issue is still relevant, please leave a comment or provide updated details. Thank you.

@nextjs-bot nextjs-bot added the stale The issue has not seen recent activity. label May 20, 2025
@nextjs-bot
Copy link
Collaborator

This issue has been automatically closed due to two years of inactivity. If you’re still experiencing a similar problem or have additional details to share, please open a new issue following our current issue template. Your updated report helps us investigate and address concerns more efficiently. Thank you for your understanding!

@nextjs-bot nextjs-bot closed this as not planned Won't fix, can't repro, duplicate, stale May 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. stale The issue has not seen recent activity.
Projects
None yet
Development

No branches or pull requests

5 participants