amannn / next-intl

🌐 Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.58k stars 236 forks source link

[Docs]: Change locale in App Router without-i18n-routing #1334

Closed dellorogiulio closed 2 months ago

dellorogiulio commented 2 months ago

Link to page

https://next-intl-docs.vercel.app/docs/getting-started/app-router/without-i18n-routing

Describe the problem

I'm using next-intl in the App Router without-i18n-routing configuration. Point 3 of the linked documentation reports:

export default getRequestConfig(async () => {
  // Provide a static locale, fetch a user setting, <------
  // read from `cookies()`, `headers()`, etc.
  const locale = 'en';

  return {
    locale,
    messages: (await import(`../../messages/${locale}.json`)).default
  };
});

But say nothing about how to handle changes in that user setting.

As example, consider the case in which the language is stored in a database (language is a general app setting). When someone changes the database, we expect the language to change too. So we need a way to refresh the getLocale() calling.

Currently, the only way I found to achieve this is by using both revalidatePath("/", "layout") (on the server) and router.refresh() (on the client)

I have a subscription on my database key changes, once I see a change, i trigger a rootLayout revalidation by using revalidatePath("/", "layout") and then notify the client to refresh the router via router.refresh()

But this solution does not seem stable (see below).

My question (and suggestion for a doc updates) is: is this the correct way to handle locale changes without-i18n-routing?

NOTE:

I said that 'seems not stable' because I saw that next js hits cache while revalidating path. In fact, I see the cookie x-nextjs-cache: HIT in the header response of the revalidatePath("/", "layout")

Looking at your 790, it seems to me that all the magic to avoid cache hitting is done in the middleware, which is not required in the without-i18n-routing

amannn commented 2 months ago

But say nothing about how to handle changes in that user setting.

The reason is because this really depends on the approach that you've used in your app.

If you're using a cookie-based approach, you might want to refer to the example App Router without i18n routing that is linked at the bottom of the getting started guide you're referring to.

While creating the example I've found that it's sufficient to call cookies.set(…) in a Server Action for the app to update when using cookies. Next.js is updating its cache heuristics with the upcoming version 15, therefore it might not be a good time to add docs yet, because they might get outdated soon.

Depending on your app, esp. if you don't use cookies, you might need to call router.refresh() or revalidatePath as you've mentioned. Maybe I'll add further docs about this in the future, but for now the example or the Next.js docs are the best source for finding an approach that works for you.

I'm going to move this to a discussion for now.