Skip to content
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

Next [14.2.3] Custom headers not working when using redirect in middleware #65702

Closed
404nnotfoundddd opened this issue May 13, 2024 · 6 comments
Labels
bug Issue was opened via the bug report template. Middleware Related to Next.js Middleware

Comments

@404nnotfoundddd
Copy link

Link to the code that reproduces this issue

https://github.com/404nnotfoundddd/nextjs-headers-issue

To Reproduce

  1. Start the application
  2. Go to home and you should redirected to about page
  3. Then you see pathname is not provided even if i added x-current-path header in middleware

Current vs. Expected behavior

I expected to add custom headers when using NextResponse.redirect()

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #115-Ubuntu SMP Mon Apr 15 09:52:04 UTC 2024
  Available memory (MB): 15856
  Available CPU cores: 8
Binaries:
  Node: 20.12.2
  npm: 10.3.0
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 14.2.3 // Latest available version is detected (14.2.3).
  eslint-config-next: 14.2.3
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.4.5
Next.js Config:
  output: N/A

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

Middleware

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

next dev (local), Vercel (Deployed)

Additional context

I recently realized that the only way to get pathname from server component is to create custom header with middleware. However, when I use redirect when making internationalized routes, custom headers are invalidated by nextjs. Maybe I am wrong, I would appreciate your help.

@404nnotfoundddd 404nnotfoundddd added the bug Issue was opened via the bug report template. label May 13, 2024
@github-actions github-actions bot added the Middleware Related to Next.js Middleware label May 13, 2024
@icyJoseph
Copy link
Contributor

icyJoseph commented May 13, 2024

Is the issue here that, redirect actually answers back to the client. The browser then follows the redirect Location header, but, it doesn't include any other headers it receives from the server, when doing so. This is likely what's happening here.

To get pathnames in Server Components, if you can build them within the entry page.tsx, you can use the cache trickimplementation, and then have them available downstream.

@404nnotfoundddd
Copy link
Author

Is the issue here that, redirect actually answers back to the client. The browser then follows the redirect Location header, but, it doesn't include any other headers it receives from the server, when doing so. This is likely what's happening here.

To get pathnames in Server Components, if you can build them within the entry page.tsx, you can use the cache trickimplementation, and then have them available downstream.

Can you explain this more, I don't understand it "if you can build them within the entry page.tsx, you can use the cache trickimplementation, and then have them available downstream."

@icyJoseph
Copy link
Contributor

icyJoseph commented May 14, 2024

Like, you can make something lke:

// pseudo-code !-----
const createContainer = cache(() => {
    const container = { current: null };
    const getter = () => container.current;
    const setter = (next) => { container.current = next };
    return [getter, setter]
});

export const [getSomeData, setSomeData] = createContainer();

And now you can set some data, at page level for example, with the pathname, and then get it down in the SSR tree. Importantly, this only works during the SSR pass, and because it uses cache it is scope to the current request.

Here's an actual demo of it: https://stackblitz.com/edit/nextjs-q3dnp8?file=app%2Fpage.tsx,app%2FLocaleSwitch.tsx,app%2F[locale]%2Fpage.tsx,app%2Fserver-context.ts - using a Map instead

And a more long winded explanation: #63298 (comment)

And an NPM package that implements this nicely for you: https://www.npmjs.com/package/server-only-context

@404nnotfoundddd
Copy link
Author

Like, you can make something lke:

// pseudo-code !-----
const createContainer = cache(() => {
    const container = { current: null };
    const getter = () => container.current;
    const setter = (next) => { container.current = next };
    return [getter, setter]
});

export const [getSomeData, setSomeData] = createContainer();

And now you can set some data, at page level for example, with the pathname, and then get it down in the SSR tree. Importantly, this only works during the SSR pass, and because it uses cache it is scope to the current request.

Here's an actual demo of it: https://stackblitz.com/edit/nextjs-q3dnp8?file=app%2Fpage.tsx,app%2FLocaleSwitch.tsx,app%2F[locale]%2Fpage.tsx,app%2Fserver-context.ts - using a Map instead

And a more long winded explanation: #63298 (comment)

And an NPM package that implements this nicely for you: https://www.npmjs.com/package/server-only-context

I checked your reply and the npm package you mentioned and thanks it solved my prop drilling issue, but is the header not being included when using location/redirect the default behavior of the browser or is it a nexjts error? should the issue remain open

@icyJoseph
Copy link
Contributor

icyJoseph commented May 14, 2024

You can do a little experiment. Open the browser Network on DevTools, and check the preserve log option.

Then do the navigation that does your redirect.

Inspect the headers sent by the browser upon redirect, when it follows the location header.

Or you could just trust this Stack overflow answer, https://stackoverflow.com/a/1969728

@404nnotfoundddd
Copy link
Author

I see, thanks my problem is solved

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. Middleware Related to Next.js Middleware
Projects
None yet
Development

No branches or pull requests

2 participants