amannn / next-intl

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

Support dynamic locale in static generation server component #1225

Closed devrsi0n closed 2 months ago

devrsi0n commented 3 months ago

Is your feature request related to a problem? Please describe.

Currently, I didn't find a way to support dynamic locale in static generation server component.

Here is my scenario: I have a complex nextjs app, it includes multi-tenant sites /app/blog/[domain], dashboard /app/dashboard and landing page /app/root.

In a multi-tenant route /app/blog/[domain], user can choose a locale (en/jp) from site settings. After reading the doc, I found that in server components, all messages are read from i18n.ts. However, without other params, I can't get site settings inside i18n.ts, thus I can't setup locale for that route.

Describe the solution you'd like

We can inject messages directly into server components, so useTranslations won't error Could not resolve xxx in messages for locale en.

Describe alternatives you've considered

I'm converting all server components to client components to leverage NextIntlClientProvider to read the right messages. It's not very ideal IMO. We lost all benefits of server components.

devrsi0n commented 3 months ago

Hey @amannn would you mind take a look? Thanks in advance

amannn commented 3 months ago

Hey! I've been on vacation for a few weeks, sorry for the late reply.

Is there a [locale] segment somewhere in your pathname? If yes, this might be a duplicate of https://github.com/amannn/next-intl/issues/1107. If not, you should be able to derive a locale from the domain by reading this in i18n.ts (see: Setup without i18n routing: i18n.ts).

Does that cover your use case?

devrsi0n commented 3 months ago

Hey @amannn thanks for the reply. Unfortunately, I can't read domain from i18n.ts, because it'll convert /app/blog/[domain] into SSR (reading headers in this case), but we need static generation here. Is it possible to inject messages into the message source of useTranslations when SSG? Thus we don't need i18n.ts at all.

amannn commented 3 months ago

How do the public pathnames look like to the user? Is [domain] visible? Is there a [locale] segment, or does a domain only support a single locale? Can you provide an overview of how pathnames look like to the user and what needs to be matched internally?

There was a very similar case discussed here: https://github.com/amannn/next-intl/issues/1107#issuecomment-2152373012 (see the note with the adapted x-middleware-rewrite header). This turned out to work for a user. Maybe this is helpful to you!

Is it possible to inject messages into the message source of useTranslations when SSG?

I don't think that's possible, no. i18n.ts is always consulted to load i18n config for Server Components.

devrsi0n commented 3 months ago

@amannn Sorry for the delay. Yes, the domain only support one single locale, we don't have [locale] or anything similar in the path, we save the locale to a db and read it when SSG. I took a glance of the issues you mentioned, I don't think read db in middleware is ideal, the latency would be unacceptable...

amannn commented 2 months ago

I see. If SSG is mandatory anyway, you could consider using unstable_setRequestLocale to pass a locale depending on a domain to next-intl. You need to ensure that this is consistently called in each layout and page before any calls to next-intl happen.

Ideally you'd be able to return a locale based on a [domain] segment in i18n.ts, but Next.js currently doesn't support that (see https://github.com/amannn/next-intl/issues/663).

amannn commented 2 months ago

One more thought: You do have an infinite number of domains, is that correct? Otherwise the domains configuration setting from next-intl should already support your use case well.

amannn commented 2 months ago

I'm going to close this issue, as this is mostly covered in https://github.com/amannn/next-intl/issues/1107.