refactor(next): use built-in Pages Router i18n - #2004
Merged
Conversation
Contributor
size-limit report 📦
|
Contributor
Author
Contributor
Author
Contributor
Author
Contributor
Author
eoinest
enabled auto-merge (squash)
July 29, 2026 23:05
Merged
eoinest
pushed a commit
that referenced
this pull request
Jul 29, 2026
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## gt-next@11.1.3 ### Patch Changes - [#2004](#2004) [`e54d376`](e54d376) Thanks [@eoinest](https://github.com/eoinest)! - Delegate Pages Router locale routing and active-locale resolution to Next.js internationalized routing. Pages data wrappers prefer `context.locale` while retaining the previous request detector as a compatibility fallback, `withGTConfig` selects `NEXT_LOCALE` when Next.js locale detection is enabled, and applications can navigate with the Pages Router locale option through the existing provider reload callback. App Router middleware and `GTProvider` behavior are unchanged. - Updated dependencies []: - @generaltranslation/react-core@11.1.3 - gt-react@11.1.3 ## gt-react@11.1.3 ### Patch Changes - Updated dependencies []: - @generaltranslation/react-core@11.1.3 ## gt-react-native@11.1.3 ### Patch Changes - Updated dependencies []: - @generaltranslation/react-core@11.1.3 ## gt-tanstack-start@11.1.3 ### Patch Changes - Updated dependencies []: - @generaltranslation/react-core@11.1.3 - gt-react@11.1.3 ## @generaltranslation/react-core@11.1.3 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
eoinest
added a commit
that referenced
this pull request
Jul 30, 2026
## Summary - Warn when explicitly configured `defaultLocale` or `locales` values in the GT config file differ from Next.js internationalized routing. - Compare locale lists without treating order as a mismatch, and leave the user-owned Next.js `i18n` configuration unchanged. ## Testing - `pnpm --filter gt-next test:js` — passed (25 files, 268 tests) - `pnpm --filter gt-next typecheck` — passed - `pnpm --filter gt-next build:no-swc-plugin` — passed - `pnpm exec oxlint packages/next/src/config.ts packages/next/src/errors/createErrors.ts packages/next/src/__tests__/config.test.ts` — passed - `pnpm exec oxfmt --check packages/next/src/config.ts packages/next/src/errors/createErrors.ts packages/next/src/__tests__/config.test.ts .changeset/next-i18n-config-mismatch-warning.md` — passed ## Notes - Stacked on `e/next/refactor-nextjs-pages` / #2004. - Changeset: added a patch changeset for `gt-next`. <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR adds a build-time advisory warning when locale settings in the GT config file (`gt.config.json`) diverge from Next.js's built-in internationalized routing config (`i18n.defaultLocale` / `i18n.locales`). The comparison is order-independent, deduplication-safe, and accounts for GT's own normalization that prepends `defaultLocale` into the effective locale set. - Adds `getNextI18nConfigMismatches` (private) and `haveSameLocales` helpers in `config.ts`, with the check deliberately scoped to file-loaded config only (inline `props` continue through existing conflict/merge paths). - Adds `createNextI18nConfigMismatchWarning` to the diagnostic helpers in `createErrors.ts` and wires it in just after the GT config file is loaded, before environment variables are resolved. - Covers the new paths with five focused tests (mismatch fires, order-safe, defaultLocale-omitted-from-locales, deduplication, no-i18n guard). <details open><summary><h3>Confidence Score: 5/5</h3></summary> Safe to merge — the change is purely additive, emitting an advisory console warning at build time without modifying any runtime behavior or Next.js config output. The new mismatch-detection logic is well-scoped (file-loaded config only), order-independent, and correctly normalizes the GT locale set before comparison. Previous review thread concerns (false-positive when defaultLocale is omitted from locales, duplicate deduplication, inline-props scope) are all addressed with tests. No runtime paths are affected. **Files Needing Attention:** No files require special attention. </details> <details><summary><h3>Important Files Changed</h3></summary> | Filename | Overview | |----------|----------| | packages/next/src/config.ts | Adds getNextI18nConfigMismatches and haveSameLocales helpers; wires warning after GT config file load. Logic correctly handles order-independence, defaultLocale prepend, and deduplication edge cases. | | packages/next/src/errors/createErrors.ts | Adds createNextI18nConfigMismatchWarning using the existing plugin diagnostic format; consistent with other warnings in the file. | | packages/next/src/__tests__/config.test.ts | Adds five targeted tests covering: mismatch detection, order-independence, defaultLocale prepend normalization, duplicate deduplication, and no-i18n guard. All regression cases from previous review threads are covered. | | .changeset/next-i18n-config-mismatch-warning.md | Patch changeset for gt-next, correctly categorized as non-breaking user-visible change. | </details> <details><summary><h3>Flowchart</h3></summary> ```mermaid %%{init: {'theme': 'neutral'}}%% flowchart TD A[withGTConfig called] --> B[Load GT config file] B --> C{internalNextConfig.i18n present?} C -- No --> E[Skip mismatch check] C -- Yes --> D[getNextI18nConfigMismatches] D --> F{gtConfig.defaultLocale !== undefined AND !== nextI18n.defaultLocale?} F -- Yes --> G[Push defaultLocale mismatch string] F -- No --> H G --> H{gtConfig.locales !== undefined AND haveSameLocales returns false?} H -- Yes --> I[Push locales mismatch string] H -- No --> J I --> J{mismatches.length > 0?} G --> J J -- Yes --> K[console.warn with createNextI18nConfigMismatchWarning] J -- No --> L[Continue build normally] E --> L K --> L ``` </details> <sub>Reviews (3): Last reviewed commit: ["chore: merge latest main into i18n confi..."](33c5718) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=48518447)</sub> <!-- /greptile_comment -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
i18nobject and configure GT to useNEXT_LOCALEonly when Next.js locale detection is enabledGTProviderunchanged and document the application-owned_reloadcallback for locale-aware Pages Router navigationTesting
pnpm --filter gt-next test:js— passed, 265 testspnpm --filter gt-next typecheckpnpm --filter next-pages-router typecheckpnpm --filter gt-test-next-pages-router typecheckpnpm --filter gt-test-apps-e2e typecheckpnpm exec oxlint packages/next/src/config.ts packages/next/src/__tests__/config.test.ts examples/next-pages-router/src/pages/_app.tsx tests/apps/next-pages-router/pages/_app.tsx tests/apps/test-apps-e2e/e2e/app.spec.tspnpm --filter gt-next build:no-swc-pluginpnpm --filter next-pages-router exec next build— Next.js 15 SSG passedpnpm --filter gt-test-next-pages-router build— Next.js 16 Pages Router passedGT_TEST_APPS=next-pages-router pnpm --filter gt-test-apps-e2e test:e2e— locale routes,html lang, translations, andNEXT_LOCALEpassedpnpm --filter gt-test-next-app-router build— App Router passedpnpm check:library-defaultsNotes
localeDetectionas enabled;localeDetection: falsepreserves the existing GT cookie configuration.gt-next.Greptile Summary
This PR delegates Pages Router locale resolution and URL routing to Next.js built-in i18n, replacing gt-next's own request-based locale detection as the primary mechanism while keeping the old detector as a compatibility fallback. The App Router,
GTProvider, and middleware paths are untouched.withGTConfignow overrideslocaleCookieNametoNEXT_LOCALEwheni18n.localeDetectionis enabled (the Next.js default), aligning GT's client-side persistence with the router's own cookie.parseLocaleandwithGTStaticPropsprefercontext.localeinjected by Next.js;resolvePagesRouterLocaleprovides a graceful fallback tocontext.defaultLocalewith a warning whencontext.localeis absent.gt-reacttogt-next, addingi18nconfig tonext.config.tsand an application-owned_reloadcallback to_app.tsxfor locale navigation.Confidence Score: 5/5
Safe to merge; all locale-resolution paths are covered by unit and E2E tests and the core library logic is correct.
The locale-priority change (context.locale → legacy fallback) is well-tested across getStaticProps and getServerSideProps paths, and the cookie-name override to NEXT_LOCALE is intentional and verified. No logic errors, data-loss scenarios, or auth-boundary issues were found in the changed code.
Files Needing Attention: packages/next/src/config.ts — the NEXT_LOCALE cookie-name override silently discards user-supplied custom cookie names when locale detection is enabled; may warrant a build-time notice for clarity.
Important Files Changed
nextLocaleDetectionEnabledcheck that silently overrideslocaleCookieNametoNEXT_LOCALEwhenever Next.js locale detection is enabled, taking priority over any user-supplied cookie name.context.localefrom Next.js i18n routing over legacy request detection; addsresolvePagesRouterLocalefor static-props use; retains legacy detector as deprecated fallback. Logic and warnings look correct.!context.localeto!context.locale && !context.defaultLocale, allowing graceful fallback viaresolvePagesRouterLocalewhen onlydefaultLocaleis available; correct and well-tested.nextLocaleCookieName = 'NEXT_LOCALE'constant with correct documentation link; minimal and correct.createMissingPagesRouterLocaleWarningthat correctly reports the resolved (post-fallback) locale, addressing the previously noted warning-accuracy concern.context.localepriority, legacy fallback paths, unsupported locales, and alias handling; also validates the fixed warning-message accuracy for the unsupporteddefaultLocalecase._reloadcallback for locale-aware navigation;Component {...pageProps}now forwardslocale,translations, andenableI18nto every page component rather than stripping them.NEXT_LOCALEcookie override when locale detection is enabled, cookie preservation when detection is disabled, and i18n config passthrough — all correctly aligned with the implementation.html langattribute,NEXT_LOCALEcookie presence, and translation rendering after locale switch; coverage looks solid.Sequence Diagram
sequenceDiagram participant NextJs as Next.js Router participant getStaticProps as withGTStaticProps / withGTServerSideProps participant parseLocale as parseLocale / resolvePagesRouterLocale participant GTProvider as GTProvider (_app.tsx) participant Cookie as NEXT_LOCALE cookie NextJs->>getStaticProps: "context { locale, defaultLocale }" alt context.locale is set (i18n enabled) getStaticProps->>parseLocale: resolvePagesRouterLocale(context) parseLocale-->>getStaticProps: returns context.locale (validated) else context.locale undefined, defaultLocale set (legacy fallback) getStaticProps->>parseLocale: resolvePagesRouterLocale(context) parseLocale-->>getStaticProps: returns resolved defaultLocale + emits warning else both undefined getStaticProps-->>NextJs: throws withGTStaticPropsLocaleRoutingError end getStaticProps-->>GTProvider: "pageProps { locale, translations }" GTProvider->>Cookie: writes NEXT_LOCALE (when localeDetection enabled) GTProvider-->>NextJs: "_reload({ locale }) → Router.push(pathname, asPath, { locale })" NextJs->>NextJs: "navigates to /<locale>/path, updates NEXT_LOCALE cookie"Reviews (4): Last reviewed commit: "docs(next): remove Pages Router migratio..." | Re-trigger Greptile