Skip to content

fix(nextjs): resolve the UI language on the server so hydration does not fail - #564

Open
DonOmalVindula wants to merge 1 commit into
asgardeo:mainfrom
DonOmalVindula:fix/nextjs-i18n-ssr-language
Open

fix(nextjs): resolve the UI language on the server so hydration does not fail#564
DonOmalVindula wants to merge 1 commit into
asgardeo:mainfrom
DonOmalVindula:fix/nextjs-i18n-ssr-language

Conversation

@DonOmalVindula

Copy link
Copy Markdown
Contributor

Problem

@asgardeo/react's I18nProvider picks the initial language in a state initialiser from preferences.language, then the lang URL parameter, then its storage (a cookie by default), then navigator.language. On the server none of the browser-side sources exist, so the server render used en-US while the client render could pick fr-FR, en-GB, a persisted cookie value or a ?lang= override. Every translated text rendered on first paint (button labels, headings of the embedded forms) then mismatched and React logged hydration errors.

Fix

  • AsgardeoServerProvider resolves the language the way the client would detect it: the persisted cookie (preferences.i18n.storageKey, default asgardeo-i18n-language, when the storage strategy is the default cookie), then the first language of Accept-Language (which mirrors navigator.language). An explicitly configured preferences.i18n.language always wins.
  • AsgardeoClientProvider combines that with the lang URL parameter (or the configured urlParam), which both renders can read through useSearchParams, and passes the result as preferences.i18n.language to the i18n provider. Language switches at runtime keep working and are persisted by the i18n provider as before.
  • New resolveRequestLanguage utility with unit tests.

With the localStorage storage strategy the server cannot see the stored value, so only Accept-Language is used there.

Testing

  • pnpm lint, tsc --noEmit and pnpm vitest run (64 tests) for @asgardeo/nextjs. The provider changes are covered by review; there is no component test setup in this package.

Changeset included (@asgardeo/nextjs patch).

🤖 Generated with Claude Code

…not fail

The i18n provider detected the language from the browser and its cookie on
the client only, while the server rendered en-US, so translated texts (e.g.
the sign-in button label) produced hydration errors whenever the browser
language, the persisted cookie or a `?lang=` parameter differed.

- The server provider resolves the language the way the client would
  (persisted cookie, then Accept-Language) and passes it down.
- The client provider adds the `lang` URL parameter, which both renders can
  see, and hands the result to the i18n provider unless
  preferences.i18n.language is configured explicitly.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 49 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: b16b6159-02f7-4224-b87e-cce356a81675

📥 Commits

Reviewing files that changed from the base of the PR and between 409ebae and ea2522d.

📒 Files selected for processing (5)
  • .changeset/nextjs-i18n-ssr-language.md
  • packages/nextjs/src/client/contexts/Asgardeo/AsgardeoProvider.tsx
  • packages/nextjs/src/server/AsgardeoProvider.tsx
  • packages/nextjs/src/utils/__tests__/resolveRequestLanguage.test.ts
  • packages/nextjs/src/utils/resolveRequestLanguage.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@asgardeo-github-bot

Copy link
Copy Markdown

🦋 Changeset detected

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants