-
-
Notifications
You must be signed in to change notification settings - Fork 210
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
Persisting state and context on locale change in nextjs 13 and next-intl #496
Comments
Is this vercel/next.js#44793? This might be outside of the control of |
Hello, |
Hmm, where are you creating your zustand store? I haven't used this so far, but I could imagine if the code where the store is created remains loaded, then the state should be retained. If you're using React Context, I think if you add a provider in |
There hasn't been any updates in this thread, I'm closing this due to inactivity. Please open a new issue in case you see a bug that is caused by |
same problem,anybody solved it? |
For me i had the problem when clicking on the language toogle. How i fixed it is by defining the language toogle as 'use client' and add
to my respective layout that contained my toggle. |
In my case I have solved this issue by using window object to store data like this: you also have to add someData.d.ts in src to ensure ts error |
Description
I am building a nextjs (v13) app routed website that uses next-intl for internationalization.
I am trying to figure out a way to have some context and state persist on locale change.
When locale is changed on the page, next-intl useRouter API is used to direct to the correct locale route: app/[locale]/...rest. This seems to reset everything, including context that is not a child of NextIntlClientProvider.
I am using Prefix-based routing ('example.com/en/...rest', or 'example.com/nl/...rest') which is default.
------ My folder structure looks like this (following next-intl docs): ------
├── messages
│ ├── en.json
│ └── nl.json
├── middleware.ts
├── contexts
│ ├── testContext.tsx
└── app
└── [locale]
├── layout.tsx
└── page.tsx
------ '/middleware.ts' looks like this: ------
import createMiddleware from "next-intl/middleware";
export default createMiddleware({
locales: ["en", "nl"],
defaultLocale: "en",
});
export const config = {
matcher: ["/((?!api|_next|.\..).*)"],
};
------ '/contexts/testContext.tsx' looks like this: ------
"use client";
import {
Dispatch,
ReactNode,
SetStateAction,
createContext,
useState,
} from "react";
type TestContext = {
showDiv: boolean;
setShowDiv: Dispatch<SetStateAction>;
};
export const TestContext = createContext<TestContext | null>(null);
const TestContextProvider = ({ children }: { children: ReactNode }) => {
const [showDiv, setShowDiv] = useState(false);
return (
<TestContext.Provider value={{ showDiv, setShowDiv }}>
{children}
</TestContext.Provider>
);
};
export default TestContextProvider;
------ And the '/app/[locale]/layout.tsx' is as follows: ------
import { NextIntlClientProvider } from "next-intl";
import { notFound } from "next/navigation";
import TestContextProvider from "@/contexts/testContext";
export function generateStaticParams() {
return [{ locale: "en" }, { locale: "nl" }];
}
export default async function RootLayout({
children,
params: { locale },
}: {
children: React.ReactNode;
params: { locale: string };
}) {
let messages;
try {
messages = (await import(
../../messages/${locale}.json
)).default;} catch (error) {
notFound();
}
return (
{children}
);
}
This is a testProject to specify this issue. In another- real- project this functionality would allow for (i.e.) my stateful dropdown menu (which includes a locale switch button) to remain in a state op being opened on locale change (which is being stored in a context outside of NextIntlClientProvider).
I have tried using the various UseRouter, UsePathname, Link and other hooks that are offered by next-intl as an extension of the native nextjs UseRouter, UsePathname and other hooks and functions, expecting this to take into consideration the specificities of locale switching (which ought to switch locale with the least amount of disruption.)
I have tried nesting the NextIntlClientProvider more deeply in the RootLayout, thereby only affecting more nested components. But this still triggered a total reset of external state and context.
I have tried relocating the RootLayout.tsx before the [locale] folder, thereby preventing the locale and route change to affect RootLayout (which holds my state and context). However, this would mean my Rootlayout can't use the internationalization as it is no longer embedded into the locale detection flow. Furthermore, if I would want to use internationalized metadata that uses translations, I would need to locate this within the [locale] detection and flow.
Mandatory reproduction URL (CodeSandbox or GitHub repository)
https://github.com/woutervdlaan/intl-test-app
Reproduction description
Steps to reproduce:
Open repo
Clone repo
run 'npm run dev' and go to localhost:3000
when clicking on button 'LANGUAGE CHANGE' the locale switches and language is changed (Hello world => Hallo wereld) and this should ALSO setState of showDiv, which is stored in testContext outside of NextIntlClientProvider
page refreshes and context is reset instead of persisted.
Expected behaviour
TestContext is stored outside of NextIntlClientProvider, therefore I expect only relevant components to remount and NOT TestContext. How can it be that is still seems to reload page entirely?
The text was updated successfully, but these errors were encountered: