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

feat: Support providing a locale in i18n.ts instead of reading it from the pathname #1017

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

amannn
Copy link
Owner

@amannn amannn commented Apr 24, 2024

Resolves #960

Use cases

  1. Apps where the locale should be read from user settings instead of the [locale] segment
  2. Apps where only a single locale is supported

Prerelease

npm install next-intl@3.12.0-provided-locale.1

Changes

The gist is instead of reading the locale from the argument that's passed to getRequestConfig in i18n.ts you can now return a locale from the function:

// i18n.ts
import {getRequestConfig} from 'next-intl/server';

export default getRequestConfig(async () => {
  // This can either be defined statically if only a single locale
  // is supported, or alternatively read from user settings
  const locale = 'en';

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

This simplified setup comes with some benefits:

  1. No [locale] segment needs to be added
  2. No routing APIs need to be used (middleware, navigation APIs)
  3. Static rendering works without tradeoffs if you only support a single language

Example implementation

Docs changes

  • Provide a separate getting started guide for usage without i18n routing
  • Remove overview/index pages from table of contents (expandable areas now have a main click area and the expand icon button)
  • Adapt docs where necessary to cater to both use cases (with/without i18n routing)

Proposed docs

Copy link

vercel bot commented Apr 24, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-intl-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 14, 2024 2:31pm
next-intl-example-app-router ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 14, 2024 2:31pm

@belgattitude
Copy link

Would be awesome ! Thx for your work

@AhmedBaset
Copy link
Contributor

  1. Static rendering works without tradeoffs

How is Static rendering supposed to work for more than one locale (most cases)?

If the value is derived from a runtime variable, such as userSession, then Dynamic Rendering will be opted for. If the value comes from predefined routes, such as ["en", "de"], then only one locale will be generated, which contradicts the concept of internationalization.

@amannn
Copy link
Owner Author

amannn commented May 1, 2024

@AhmedBaset Yep, that's of course correct—thanks for the feedback! The statement only applies to using a single language, I've changed it accordingly above.

@amannn
Copy link
Owner Author

amannn commented May 7, 2024

My main concern with this currently is that the locale is returned asynchronously.

Looking through all the options we support in i18n.ts, I think they can be grouped like this:

  1. Definitely not async: formats, defaultTranslationValues, onError
  2. Likely not async: now
  3. Might be async: locale (if read from user profile), timeZone
  4. Likely async: messages

So generally, it seems reasonable that we support an async config object.

However, this currently has the implication that the locale can't be read synchronously during an RSC render. This is mostly not an issue, but the navigation APIs are affected by this. For Link it's no problem since we can make the component async, but for redirect this makes a difference.

I need to investigate if there's a way where we can call redirect before we know which locale we're redirecting to …

Note that as long as we advertise this feature as something to be used without routing APIs from next-intl, this would be fine. I do however have the hope that this could pave the path to a very customizable solution to #653, in case the user could read parts of the pathname deeply in an RSC render (see vercel/next.js#58862). Let's see.

EDIT: Declaring this a non-issue for now as routing APIs don't need to be used when you're not using i18n routing. Note to self though, in case we move to a place in the future where the locale is generally returned from i18n (i.e. Next.js allows to read params deeply), we could make the locale a mandatory argument for redirect. Not super elegant, but given all other aspects that this enables (e.g. market prefixes), possibly something worth considering.

# Conflicts:
#	packages/next-intl/package.json
#	pnpm-lock.yaml
# Conflicts:
#	docs/pages/docs/getting-started/app-router.mdx
# Conflicts:
#	docs/pages/docs/environments.mdx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants