-
Notifications
You must be signed in to change notification settings - Fork 29.1k
Description
Link to the code that reproduces this issue
https://github.com/dmitrc/nextjs-packagelocalizationprovider-repro
To Reproduce
- Start the dev server (
next start
behaves the same way) - Navigate to /test and press "Check" button
- Observe that a global value set from LocalizedStringProvider's script has been set

- Now navigate to /zzz (that will 404) and press "Check" button
- Observe that a global value set from LocalizedStringProvider's script has NOT been set

- Search for
window[Symbol.for('react-aria.i18n.locale')]
in the DOM to find the relevant script (meaning it was rendered, but not executed)

- Now remove the parallel route by deleting
@modal
folder and corresponding layout slot - Restart the dev server
- Repeat the test above, and observe that it works as expected now

Current vs. Expected behavior
This issue is weird, but I was able to isolate it to the minimal repro linked above.
Concepts
React-Aria's LocalizedStringProvider is a server-side component that writes a <script>
which puts some strings in a global variable on window
. This is normally included in the server-side layout output, and allows to optimize the client JS bundle by only pre-baking the strings for the specific locale that the user needs.
not-found.tsx file in the root allows to show custom UI when notFound()
was invoked or none of the routes have matched. This clearly follows some different rendering path, as it starts with an almost-blank page, and then streams stuff in, including the root layout.
Parallel routes allow to render two slots of UI at once, based on the concurrent routing to the main app model and @slot
. In our app, we render a dynamic route for all pages, allowing us to embed a modal or a custom view on all "normal" pages. I am not sure how this plays out in the whole picture here, but when you remove this, everything works as expected.
Issue
When loading the normal routes directly, the script is rendering and executed as intended, so React-Aria components are able to get the locale and corresponding strings. "Check" button of this demo does a crude check directly from window
to showcase the results.
However, when going through a not found route (same thing happens on error handlers too), the rendering takes a different path. The page starts blank. the layout is streamed in, the <script>
tag is present in the DOM, but it never executes somehow. The "Check" button reveals that the global value is undefined
. If you were to embed a <Popover>
or other React-Aria component requiring these strings on that page, it would throw (which is what brings me here today).
Observations
At first, I thought it was a generic defect of streamed layouts in the context of not found / error handlers, but this issue does not occur when removing the usage of the parallel routes.
Provide environment information
Operating System:
Platform: linux
Arch: x64
Version: #1 SMP Tue Nov 5 00:21:55 UTC 2024
Available memory (MB): 32022
Available CPU cores: 32
Binaries:
Node: 22.16.0
npm: 10.9.2
Yarn: N/A
pnpm: 9.15.4
Relevant Packages:
next: 15.4.6 // Latest available version is detected (15.4.6).
eslint-config-next: N/A
react: 19.1.0
react-dom: 19.1.0
typescript: 5.9.2
Next.js Config:
output: N/A
Which area(s) are affected? (Select all that apply)
Parallel & Intercepting Routes, Not Found, Error Handling
Which stage(s) are affected? (Select all that apply)
next dev (local), next start (local)
Additional context
No response