-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
examples: add intlayer i18n example #6039
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
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new React example demonstrating Intlayer-based i18n with locale-prefixed TanStack Router routes, generated route tree and router factory, server-side locale resolution adapter, localized components/hooks, content dictionaries (en/es/fr), and project config files (Vite, TS, Intlayer, ESLint). Changes
sequenceDiagram
participant Browser
participant Router as "TanStack Router"
participant RouteComp as "RouteComponent"
participant Intlayer as "IntlayerProvider"
participant Server
participant Storage as "LocalStorage / Cookie"
Browser->>Router: Navigate to /{locale}/path
Router->>RouteComp: mount with params.locale
RouteComp->>Intlayer: initialize provider(locale)
RouteComp->>Storage: read persisted locale (optional)
Router->>Server: request preloader / getData (headers, cookies)
Server->>Server: getLocale(adapter: headers/cookies) → getLocaleCore
Server-->>Router: return localized messages/data
RouteComp->>Router: render localized UI (Header, LocaleSwitcher, Outlet)
Browser->>RouteComp: user selects locale
RouteComp->>Storage: setLocaleInStorage(newLocale)
RouteComp->>Router: navigate to localized path (LocalizedLink / useLocalizedNavigate)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45–75 minutes
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
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. Comment |
2f6ad4d to
8344da4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (9)
examples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsx (1)
1-21: Hook correctly syncs<html>attributes with the active localeThe effect wiring and dependency on
localelook good and should behave correctly in a browser-only context.If you expect this hook to ever run in non-DOM environments (e.g. some tests or exotic runtimes), you might optionally wrap the effect body with a
typeof document !== 'undefined'check, but it’s not strictly necessary for typical Start/React usage.examples/react/start-i18n-intlayer/tsconfig.json (1)
1-36: Strict TS config looks good; minor include nitThis config hits the strictness goals (strict mode, unused checks, bundler resolution, paths) and should work well for the example.
One tiny consistency nit: the
includearray lists"vite.config.js", but the file in this example isvite.config.ts. It’s harmless because"**/*.ts"already picks it up, but you could either change that entry to"vite.config.ts"or drop it entirely for clarity.examples/react/start-i18n-intlayer/src/utils/getLocale.ts (1)
1-29: Locale resolution wiring looks correct; simplify the async wrapperThe adapters for
getAllHeaders,getCookie, andgetHeaderare consistent with the Start server helpers. ThegetAllHeaderscallback must be async per the intlayer API, which your code correctly implements.You can drop the redundant outer async/await for a cleaner signature:
-export const getLocale = async () => - await getLocaleCore({ +export const getLocale = () => + getLocaleCore({ // Fallback using Accept-Language negotiation getAllHeaders: async () => { const headers = getRequestHeaders() const result: Record<string, string> = {} // Convert the TypedHeaders into a plain Record<string, string> for (const [key, value] of headers.entries()) { result[key] = value } return result }, // Get the cookie from the request (default: 'INTLAYER_LOCALE') getCookie: (name) => { const cookieString = getRequestHeader('cookie') return getCookie(name, cookieString) }, // Get the header from the request (default: 'x-intlayer-locale') getHeader: (name) => getRequestHeader(name), })Both forms return a
Promise, but the simplified version is more idiomatic.examples/react/start-i18n-intlayer/src/components/Header.tsx (2)
5-17: Remove unnecessary React Fragment wrapper.The Fragment (
<>...</>) is redundant since the component returns only a single<header>element.return ( - <> - <header className="p-4 flex items-center bg-gray-800 text-white shadow-lg"> - <h1 className="ml-4 text-xl font-semibold"> - <LocalizedLink to="/"> - <img - src="/tanstack-word-logo-white.svg" - alt="TanStack Logo" - className="h-10" - /> - </LocalizedLink> - </h1> - </header> - </> + <header className="p-4 flex items-center bg-gray-800 text-white shadow-lg"> + <h1 className="ml-4 text-xl font-semibold"> + <LocalizedLink to="/"> + <img + src="/tanstack-word-logo-white.svg" + alt="TanStack Logo" + className="h-10" + /> + </LocalizedLink> + </h1> + </header> )
7-15: Consider semantic HTML:<h1>with only an image.Using an
<h1>that contains only an image (no visible text) may affect accessibility and SEO. Screen readers will announce "TanStack Logo" from the alt text, which works, but consider whether adding visually-hidden text (e.g., "TanStack Start") would better convey the page heading.examples/react/start-i18n-intlayer/intlayer.config.ts (1)
14-19: AI configuration included in example.The AI configuration with OpenAI API key is included. For an example project, this is fine, but ensure the README documents that
OPENAI_API_KEYmust be set if AI features are used, or consider making this section optional/commented out by default since it's not core to the i18n demonstration.examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx (1)
29-31: Minor typo: extra space in function call.There's an extra space before the closing parenthesis on line 30.
- params={{ locale: getPrefix(localeEl ).localePrefix }} + params={{ locale: getPrefix(localeEl).localePrefix }}examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts (1)
12-27: Move type definitions outside the hook.Defining types inside the hook body is non-idiomatic. While TypeScript erases types at runtime, it's cleaner to define them at module scope for reusability and readability.
+type StripLocalePrefix<T extends string> = T extends + | `/${typeof LOCALE_ROUTE}` + | `/${typeof LOCALE_ROUTE}/` + ? "/" + : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}` + ? `/${Rest}` + : never; + +type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>; + +interface LocalizedNavigate { + (to: LocalizedTo): ReturnType<typeof useNavigate>; + (opts: { to: LocalizedTo } & Record<string, unknown>): ReturnType<typeof useNavigate>; +} + export const useLocalizedNavigate = () => { const navigate = useNavigate(); const { locale } = useLocale(); - type StripLocalePrefix<T extends string> = T extends - | `/${typeof LOCALE_ROUTE}` - | `/${typeof LOCALE_ROUTE}/` - ? "/" - : T extends `/${typeof LOCALE_ROUTE}/${infer Rest}` - ? `/${Rest}` - : never; - - type LocalizedTo = StripLocalePrefix<FileRouteTypes["to"]>; - - interface LocalizedNavigate { - (to: LocalizedTo): ReturnType<typeof navigate>; - ( - opts: { to: LocalizedTo } & Record<string, unknown>, - ): ReturnType<typeof navigate>; - } - const localizedNavigate: LocalizedNavigate = (args: any) => {examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx (1)
35-38: SimplifyqueryFnwrapper.The arrow function wrapper around
getData()is unnecessary sincegetDatais already callable and returns a Promise.const { data, isPending } = useQuery({ - queryFn: () => getData(), + queryFn: getData, queryKey: ['app-message', locale], });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
examples/react/start-i18n-intlayer/public/favicon.icois excluded by!**/*.icoexamples/react/start-i18n-intlayer/public/tanstack-circle-logo.pngis excluded by!**/*.pngexamples/react/start-i18n-intlayer/public/tanstack-word-logo-white.svgis excluded by!**/*.svgpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
examples/react/start-i18n-intlayer/.gitignore(1 hunks)examples/react/start-i18n-intlayer/intlayer.config.ts(1 hunks)examples/react/start-i18n-intlayer/package.json(1 hunks)examples/react/start-i18n-intlayer/src/components/Header.tsx(1 hunks)examples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts(1 hunks)examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx(1 hunks)examples/react/start-i18n-intlayer/src/components/localized-link.tsx(1 hunks)examples/react/start-i18n-intlayer/src/content/index.content.tsx(1 hunks)examples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsx(1 hunks)examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts(1 hunks)examples/react/start-i18n-intlayer/src/routeTree.gen.ts(1 hunks)examples/react/start-i18n-intlayer/src/router.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/__root.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx(1 hunks)examples/react/start-i18n-intlayer/src/styles.css(1 hunks)examples/react/start-i18n-intlayer/src/utils/getLocale.ts(1 hunks)examples/react/start-i18n-intlayer/tsconfig.json(1 hunks)examples/react/start-i18n-intlayer/vite.config.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.tsexamples/react/start-i18n-intlayer/src/components/Header.tsxexamples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsxexamples/react/start-i18n-intlayer/src/router.tsxexamples/react/start-i18n-intlayer/vite.config.tsexamples/react/start-i18n-intlayer/src/content/index.content.tsxexamples/react/start-i18n-intlayer/intlayer.config.tsexamples/react/start-i18n-intlayer/src/utils/getLocale.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/routes/__root.tsxexamples/react/start-i18n-intlayer/src/components/locale-switcher.tsxexamples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.tsexamples/react/start-i18n-intlayer/src/components/Header.tsxexamples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsxexamples/react/start-i18n-intlayer/src/router.tsxexamples/react/start-i18n-intlayer/vite.config.tsexamples/react/start-i18n-intlayer/src/content/index.content.tsxexamples/react/start-i18n-intlayer/intlayer.config.tsexamples/react/start-i18n-intlayer/src/utils/getLocale.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/routes/__root.tsxexamples/react/start-i18n-intlayer/src/components/locale-switcher.tsxexamples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
examples/react/start-i18n-intlayer/package.json
🧠 Learnings (6)
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-i18n-intlayer/src/router.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-i18n-intlayer/src/router.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/routes/__root.tsxexamples/react/start-i18n-intlayer/tsconfig.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-i18n-intlayer/package.jsonexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/tsconfig.json
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/routes/__root.tsx
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code
Applied to files:
examples/react/start-i18n-intlayer/tsconfig.json
🧬 Code graph analysis (7)
examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts (2)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
LOCALE_ROUTE(6-6)examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
FileRouteTypes(40-47)
examples/react/start-i18n-intlayer/src/components/Header.tsx (1)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
LocalizedLink(32-45)
examples/react/start-i18n-intlayer/src/utils/getLocale.ts (1)
packages/start-server-core/src/request-response.ts (3)
getRequestHeaders(77-80)getRequestHeader(82-84)getCookie(226-228)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
Route(15-17)examples/react/start-i18n-intlayer/src/utils/getLocale.ts (1)
getLocale(7-29)
examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
examples/react/start-i18n-intlayer/src/router.tsx (1)
getRouter(7-15)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (4)
examples/react/start-i18n-intlayer/src/routes/__root.tsx (1)
Route(5-28)examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx (1)
Route(9-19)examples/react/start-i18n-intlayer/src/components/Header.tsx (1)
Header(3-19)examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx (1)
LocaleSwitcher(12-51)
examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx (1)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (2)
LocalizedLink(32-45)To(13-13)
🔇 Additional comments (15)
examples/react/start-i18n-intlayer/.gitignore (1)
1-15: Git ignore patterns look appropriate for this exampleThe ignore list covers the expected build artifacts, framework caches, and Intlayer-specific files; nothing here seems problematic.
examples/react/start-i18n-intlayer/src/content/index.content.tsx (1)
1-41: Typed dictionary shape and translations look solidThe
HomePageContentinterface matches thecontentstructure, and usingsatisfies Dictionary<HomePageContent>gives nice compile-time guarantees. Translations are consistently provided foren,es, andfr.examples/react/start-i18n-intlayer/vite.config.ts (1)
1-23: Vite plugin setup and ordering look correct
intlayerProxyrunning beforenitro, followed by tsconfig paths, Tailwind, TanStack Start, React, andintlayeris a sensible order and aligns with the comments and tooling expectations.examples/react/start-i18n-intlayer/src/styles.css (1)
1-10: Base Tailwind + typography styling is appropriateThe Tailwind import and minimal body reset/font stack are a good fit for this example and shouldn’t interfere with Tailwind’s utilities.
examples/react/start-i18n-intlayer/src/routes/__root.tsx (1)
5-28: Route configuration looks good.The root route setup with head metadata (charset, viewport, title) and stylesheet link is correctly structured for TanStack Start.
examples/react/start-i18n-intlayer/intlayer.config.ts (1)
4-47: Configuration structure is well-organized.The Intlayer configuration properly defines locales, routing mode, and build settings. The use of the
Localesenum ensures type safety.examples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts (1)
1-19: Well-structured i18n content definition.The locale switcher content follows Intlayer's dictionary pattern correctly. Good use of
satisfies Dictionaryfor type safety andinsert()for the interpolated placeholder.examples/react/start-i18n-intlayer/src/router.tsx (1)
7-15: The suggestion to add an explicit return type is well-intentioned for TypeScript strict mode compliance, but the proposed implementation is incorrect. TheRoutertype is not exported from@tanstack/react-routerfor direct import, and the return type signatureRouter<typeof routeTreeImpl>is invalid.Per TanStack Router's documentation, type safety is achieved through declaration merging with the
Registerinterface, not through explicit return type annotations on the factory function. The current implementation is acceptable and follows TanStack Router's recommended patterns.Likely an incorrect or invalid review comment.
examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx (1)
12-50: Well-structured locale switcher component.The component properly handles accessibility with
aria-current,aria-label,lang, anddirattributes. The use ofgetPathWithoutLocaleto preserve the current path during locale switches is a good pattern.examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (2)
23-40: Rendering<html>in a nested route is unconventional.This route component renders the full HTML document structure (
<html>,<head>,<body>). Typically, this would be handled in__root.tsxor ashellComponent. Verify this is intentional for TanStack Start's routing model with locale prefixes.
19-24:useLocale()requiresIntlayerProvidercontext to function correctly.The web search confirms that
useLocale()reads React context established byIntlayerProviderand must be called within a component tree wrapped by the provider. IfuseLocale()is indeed called beforeIntlayerProviderwraps the component tree (as suggested by the line numbers), the hook will fail to access the locale context.Verify that either: (1) a parent component or layout provides
IntlayerProviderat a higher level, (2) this is a server component using a server-side variant with explicit locale, or (3) the component structure needs adjustment to ensureuseLocale()is called only afterIntlayerProviderinitialization.examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
6-30: Good type-level utilities for locale handling.The
RemoveLocaleParam,CollapseDoubleSlashes, and helper types provide strong compile-time guarantees for locale-aware routing. The recursive type transformations are well-constructed.examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx (2)
31-47: Clean demonstration of client and server i18n.The component effectively shows both patterns:
useIntlayerfor client-side translations andgetDataserver function for server-rendered content. The query key includeslocaleensuring proper cache invalidation on locale changes.
11-13: No changes needed —getIntlayeris designed to handle undefinedlocaleparameter.The
intlayerMiddlewareautomatically detects the locale and providesgetIntlayerwith a default parameter. When the optional{-$locale}segment is absent andlocaleis undefined,getIntlayer('app', locale)correctly uses the middleware-detected locale instead. Adding a fallback likelocale ?? 'en'bypasses this intelligent detection and could override the user's actual locale preference.Likely an incorrect or invalid review comment.
examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
1-99: Auto-generated file — no review required.This file is automatically generated by TanStack Router and should not be manually modified. The file correctly includes the appropriate disable comments (
eslint-disable,@ts-nocheck) and documentation header. Based on learnings,routeTree.gen.tsfiles are excluded from review in TanStack Router repositories.
examples/react/start-i18n-intlayer/src/components/localized-link.tsx
Outdated
Show resolved
Hide resolved
examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts
Outdated
Show resolved
Hide resolved
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
Outdated
Show resolved
Hide resolved
8344da4 to
8ecbf82
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
49-49: Handle undefinedtoprop gracefully.The
toprop is optional (line 24), but concatenation here produces"/{-$locale}undefined"whenprops.toisundefined.- to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps['to']} + to={`/${LOCALE_ROUTE}${props.to ?? ''}` as LinkComponentProps['to']}Alternatively, make
torequired inLocalizedLinkPropsif navigation without a destination isn't valid.
🧹 Nitpick comments (3)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
45-48: Consider tightening the params type guard.
typeof null === 'object'in JavaScript. Whileprops.paramsis unlikely to benullgiven TanStack Router's types, a stricter check is more defensive:params={{ locale: getPrefix(locale).localePrefix, - ...(typeof props.params === 'object' ? props.params : {}), + ...(props.params && typeof props.params === 'object' ? props.params : {}), }}examples/react/start-i18n-intlayer/src/content/index.content.tsx (1)
3-10: Consider exportingHomePageContentfor stronger cross-module typingIf other parts of the example (hooks, components, tests) need to refer to this content shape, making the interface exported (e.g.,
export interface HomePageContent) would avoid duplicating field names and keep refactors type-safe across modules.examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
18-23: Extract a singleresolvedLocaleto avoid duplication.You compute
locale ?? defaultLocaletwice; extracting it once improves readability and keeps things in sync if the fallback logic ever changes.function RouteComponent() { - const { locale } = Route.useParams() - const { defaultLocale } = useLocale() - const [queryClient] = useState(() => new QueryClient()) + const { locale } = Route.useParams() + const { defaultLocale } = useLocale() + const resolvedLocale = locale ?? defaultLocale + const [queryClient] = useState(() => new QueryClient()) return ( - <html lang={locale ?? defaultLocale}> + <html lang={resolvedLocale}> @@ - <IntlayerProvider locale={locale ?? defaultLocale}> + <IntlayerProvider locale={resolvedLocale}>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
examples/react/start-i18n-intlayer/public/favicon.icois excluded by!**/*.icoexamples/react/start-i18n-intlayer/public/tanstack-circle-logo.pngis excluded by!**/*.pngexamples/react/start-i18n-intlayer/public/tanstack-word-logo-white.svgis excluded by!**/*.svgpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
examples/react/start-i18n-intlayer/.gitignore(1 hunks)examples/react/start-i18n-intlayer/intlayer.config.ts(1 hunks)examples/react/start-i18n-intlayer/package.json(1 hunks)examples/react/start-i18n-intlayer/src/components/Header.tsx(1 hunks)examples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts(1 hunks)examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx(1 hunks)examples/react/start-i18n-intlayer/src/components/localized-link.tsx(1 hunks)examples/react/start-i18n-intlayer/src/content/index.content.tsx(1 hunks)examples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsx(1 hunks)examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts(1 hunks)examples/react/start-i18n-intlayer/src/routeTree.gen.ts(1 hunks)examples/react/start-i18n-intlayer/src/router.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/__root.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx(1 hunks)examples/react/start-i18n-intlayer/src/styles.css(1 hunks)examples/react/start-i18n-intlayer/src/utils/getLocale.ts(1 hunks)examples/react/start-i18n-intlayer/tsconfig.json(1 hunks)examples/react/start-i18n-intlayer/vite.config.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
- examples/react/start-i18n-intlayer/.gitignore
- examples/react/start-i18n-intlayer/src/styles.css
- examples/react/start-i18n-intlayer/package.json
- examples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsx
- examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx
- examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx
- examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts
- examples/react/start-i18n-intlayer/src/router.tsx
- examples/react/start-i18n-intlayer/intlayer.config.ts
- examples/react/start-i18n-intlayer/src/components/Header.tsx
- examples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts
- examples/react/start-i18n-intlayer/src/routes/__root.tsx
- examples/react/start-i18n-intlayer/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/utils/getLocale.tsexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/content/index.content.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/utils/getLocale.tsexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/content/index.content.tsx
🧠 Learnings (6)
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code
Applied to files:
examples/react/start-i18n-intlayer/tsconfig.json
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-i18n-intlayer/tsconfig.jsonexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.ts
🧬 Code graph analysis (2)
examples/react/start-i18n-intlayer/src/utils/getLocale.ts (1)
packages/start-server-core/src/request-response.ts (3)
getRequestHeaders(77-80)getRequestHeader(82-84)getCookie(226-228)
examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
examples/react/start-i18n-intlayer/src/router.tsx (1)
getRouter(7-15)
🔇 Additional comments (7)
examples/react/start-i18n-intlayer/tsconfig.json (1)
1-36: Well-configured TypeScript setup for modern Vite + Intlayer integration.The tsconfig.json is comprehensive and follows current best practices:
- Strict mode is enabled across the board, aligning with the learning requirement for extensive type safety.
- Module resolution, target, and JSX settings are appropriate for a modern Vite-based React app.
- Inclusion of
.intlayer/types/**/*properly integrates Intlayer's generated type definitions.- The
@/*path alias for./src/*provides clean imports throughout the codebase.- All configuration files (eslint.config.ts, prettier.config.js, vite.config.js) are included for type checking.
Please confirm that
eslint.config.tsincludes TanStack Router ESLint plugin rules as per coding guidelines.examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
1-99: Skip detailed review for generated route treeThis
routeTree.gen.tsfile is clearly marked as auto-generated and, per project learnings, route tree generator outputs (likerouteTree.gen.ts) should not be manually edited or reviewed for logic, typing, or lint/style. I’m intentionally skipping further review here and assuming the generator is the source of truth.examples/react/start-i18n-intlayer/src/components/localized-link.tsx (2)
1-7: LGTM!Imports are well-organized with type-only imports separated, and
LOCALE_ROUTEcorrectly usesas constfor literal type inference.
9-37: Well-designed type utilities.The recursive type helpers (
CollapseDoubleSlashes,RemoveAll,RemoveLocaleFromString) correctly handle compile-time path normalization. The explicit type parameter naming (TVal,TString,THead,TTail) improves readability.examples/react/start-i18n-intlayer/src/content/index.content.tsx (1)
12-39: Dictionary structure andsatisfiesusage look solidThe
appContentshape matches theDictionary<HomePageContent>contract, and usingsatisfiesretains literal types while enforcing the interface, which fits strict TypeScript usage for this i18n example.examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
20-35: Per-instanceQueryClientsetup looks good for SSR.Creating the client via
useState(() => new QueryClient())inside the route component avoids module-scope cache sharing while keeping a stable client per app instance, and wrapping<Outlet />with the provider is appropriate here. This structure is solid for an example.If you later adopt the framework’s built-in QueryClient wiring elsewhere, just double-check you’re not unintentionally nesting multiple providers for the same tree.
examples/react/start-i18n-intlayer/src/utils/getLocale.ts (1)
22-26: No issues found. ThecookieStringpassed to intlayer'sgetCookieon line 25 can beundefined, but intlayer'sgetCookiefunction signature isgetCookie(name: string, cookieString?: string), where the second parameter is optional. Whenundefined, the function gracefully falls back todocument.cookieand returns either the cookie value ornull. The adapter implementation is correct.
8ecbf82 to
2340653
Compare
2340653 to
d800788
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
23-25: Guard optionaltoand tightenparamsmerge to avoid edge‑case runtime issues.Two small robustness points:
tois optional inLocalizedLinkProps, but currently interpolated directly:to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps['to']}If
props.tois ever omitted, this becomes"/{-$locale}undefined". Either maketorequired or treatundefinedas an empty string so the base locale route is used.
- The
paramsmerge usestypeof props.params === 'object', which also matchesnull. Spreadingnullwould throw if it ever slipped through, even if the current types don’t allow it.A minimal defensive change that keeps the current API:
- params={{ - locale: getPrefix(locale).localePrefix, - ...(typeof props.params === 'object' ? props.params : {}), - }} - to={`/${LOCALE_ROUTE}${props.to}` as LinkComponentProps['to']} + params={{ + locale: getPrefix(locale).localePrefix, + ...(props.params && typeof props.params === 'object' + ? props.params + : {}), + }} + to={`/${LOCALE_ROUTE}${props.to ?? ''}` as LinkComponentProps['to']}This keeps the example simple, avoids accidentally serializing
"undefined"into the path, and hardens the params spread without changing the public surface.Also applies to: 45-49
🧹 Nitpick comments (1)
examples/react/start-i18n-intlayer/package.json (1)
20-40: Consider pinning Intlayer package versions for reproducibility.The
intlayer,react-intlayer,vite-intlayer, andintlayer-editorpackages use"latest"versions, which can cause non-deterministic installs and CI variability. For a stable example, consider pinning these to specific versions (e.g.,intlayer@^0.6.0or similar). This improves reproducibility and makes dependency updates explicit.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
examples/react/start-i18n-intlayer/public/favicon.icois excluded by!**/*.icoexamples/react/start-i18n-intlayer/public/tanstack-circle-logo.pngis excluded by!**/*.pngexamples/react/start-i18n-intlayer/public/tanstack-word-logo-white.svgis excluded by!**/*.svgpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (19)
examples/react/start-i18n-intlayer/.gitignore(1 hunks)examples/react/start-i18n-intlayer/intlayer.config.ts(1 hunks)examples/react/start-i18n-intlayer/package.json(1 hunks)examples/react/start-i18n-intlayer/src/components/Header.tsx(1 hunks)examples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts(1 hunks)examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx(1 hunks)examples/react/start-i18n-intlayer/src/components/localized-link.tsx(1 hunks)examples/react/start-i18n-intlayer/src/content/index.content.tsx(1 hunks)examples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsx(1 hunks)examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts(1 hunks)examples/react/start-i18n-intlayer/src/routeTree.gen.ts(1 hunks)examples/react/start-i18n-intlayer/src/router.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/__root.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx(1 hunks)examples/react/start-i18n-intlayer/src/styles.css(1 hunks)examples/react/start-i18n-intlayer/src/utils/getLocale.ts(1 hunks)examples/react/start-i18n-intlayer/tsconfig.json(1 hunks)examples/react/start-i18n-intlayer/vite.config.ts(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- examples/react/start-i18n-intlayer/tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (12)
- examples/react/start-i18n-intlayer/.gitignore
- examples/react/start-i18n-intlayer/src/router.tsx
- examples/react/start-i18n-intlayer/src/utils/getLocale.ts
- examples/react/start-i18n-intlayer/src/hooks/useI18nHTMLAttributes.tsx
- examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx
- examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
- examples/react/start-i18n-intlayer/src/routes/__root.tsx
- examples/react/start-i18n-intlayer/src/hooks/useLocalizedNavigate.ts
- examples/react/start-i18n-intlayer/src/components/Header.tsx
- examples/react/start-i18n-intlayer/vite.config.ts
- examples/react/start-i18n-intlayer/intlayer.config.ts
- examples/react/start-i18n-intlayer/src/components/locale-switcher.content.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
examples/react/start-i18n-intlayer/src/components/locale-switcher.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/content/index.content.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
examples/react/start-i18n-intlayer/src/components/locale-switcher.tsxexamples/react/start-i18n-intlayer/src/routeTree.gen.tsexamples/react/start-i18n-intlayer/src/components/localized-link.tsxexamples/react/start-i18n-intlayer/src/content/index.content.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
examples/react/start-i18n-intlayer/package.json
🧠 Learnings (6)
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Applies to **/package.json : Use workspace protocol `workspace:*` for internal dependencies in package.json files
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-i18n-intlayer/package.jsonexamples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.210Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.210Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
examples/react/start-i18n-intlayer/src/routeTree.gen.ts
🧬 Code graph analysis (2)
examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx (1)
examples/react/start-i18n-intlayer/src/components/localized-link.tsx (2)
LocalizedLink(39-52)To(15-15)
examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
examples/react/start-i18n-intlayer/src/router.tsx (1)
getRouter(7-15)
🔇 Additional comments (5)
examples/react/start-i18n-intlayer/src/routeTree.gen.ts (1)
1-99: Autogenerated route tree – skipping detailed reviewThis file is clearly marked as auto-generated by TanStack Router and long-term repo guidance says
routeTree.gen.tsfiles should not be manually edited or reviewed. I’m treating this as generator output and won’t suggest any changes here.Based on learnings, this file is intentionally excluded from manual review.
examples/react/start-i18n-intlayer/src/styles.css (1)
1-10: LGTM! The Tailwind setup is clean and standard, with an appropriate system font stack and font-smoothing properties for cross-platform text rendering.examples/react/start-i18n-intlayer/package.json (1)
14-27: TanStack dependencies correctly use workspace protocol. ✓All internal TanStack packages (
@tanstack/react-devtools,@tanstack/react-router,@tanstack/react-start,@tanstack/router-plugin) correctly referenceworkspace:*, ensuring the example resolves to the monorepo packages.examples/react/start-i18n-intlayer/src/content/index.content.tsx (1)
1-41: Idiomatic Intlayer dictionary; types and structure look solid
HomePageContentmatches thecontentshape exactly, andsatisfies Dictionary<HomePageContent>gives good strict-mode safety without wideningappContent’s type.- Use of
tfor each localized string is consistent and keeps all user-facing text centralized in this content file.No changes needed from my side here.
If you haven’t already, double‑check that wherever you call
useIntlayeror equivalent, you’re using the'app'key so this dictionary is actually wired into the example.examples/react/start-i18n-intlayer/src/components/locale-switcher.tsx (1)
14-52: Locale switcher wiring looks correct and accessible.Nice composition of
useLocation,getPathWithoutLocale, andLocalizedLink: the per‑localeparamsoverride correctly target the new locale,aria-current="page"and the localizedaria-labelare set appropriately, anddir/langare derived from the locale. No changes needed from a routing or strict‑TS perspective here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
11-49: MoveQueryClientout of module scope to avoid SSR cross-request cache sharing. (Line 11)import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'; import { validatePrefix } from 'intlayer'; +import { useState } from 'react'; import { IntlayerProvider, useLocale } from 'react-intlayer'; @@ -const queryClient = new QueryClient(); - function RouteComponent() { + const [queryClient] = useState(() => new QueryClient()); const { defaultLocale } = useLocale(); const { locale } = Route.useParams(); useI18nHTMLAttributes(); return ( <IntlayerProvider locale={locale ?? defaultLocale}> <QueryClientProvider client={queryClient}> <Header /> <Outlet /> <LocaleSwitcher /> </QueryClientProvider> </IntlayerProvider> ); }examples/react/start-i18n-intlayer/package.json (1)
14-40: Pinnitroto a semantic version for reproducible example installs. (Line 20)Change
"nitro": "latest"to"nitro": "^2.0.0"or the appropriate stable version. Using "latest" causes non-deterministic builds; pin an exact or semver range version (with a committed lockfile) to ensure consistent installations across environments.
🧹 Nitpick comments (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx (2)
15-18: Consider addingaria-hiddento decorative elements.The animated backdrop elements are purely decorative and should be hidden from screen readers to improve accessibility.
Apply this diff to improve accessibility:
- <div className="pointer-events-none absolute inset-0 overflow-hidden"> + <div className="pointer-events-none absolute inset-0 overflow-hidden" aria-hidden="true"> <div className="absolute top-1/4 left-1/4 h-64 w-64 animate-pulse rounded-full bg-blue-500/10 blur-3xl" /> <div className="absolute right-1/4 bottom-1/4 h-96 w-96 animate-pulse rounded-full bg-purple-500/10 blur-3xl" /> </div>
10-10: Consider adding an explicit return type.For TypeScript strict mode compliance, consider adding an explicit return type annotation to the component.
Apply this diff:
-export function NotFoundComponent() { +export function NotFoundComponent(): JSX.Element {Based on coding guidelines for TypeScript strict mode.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
examples/react/start-i18n-intlayer/package.json(1 hunks)examples/react/start-i18n-intlayer/src/content/404.content.ts(1 hunks)examples/react/start-i18n-intlayer/src/content/about.content.ts(1 hunks)examples/react/start-i18n-intlayer/src/content/index.content.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routeTree.gen.ts(1 hunks)examples/react/start-i18n-intlayer/src/routes/__root.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/$.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/about.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx
- examples/react/start-i18n-intlayer/src/routeTree.gen.ts
- examples/react/start-i18n-intlayer/src/routes/__root.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/$.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/about.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsxexamples/react/start-i18n-intlayer/src/content/404.content.tsexamples/react/start-i18n-intlayer/src/content/about.content.tsexamples/react/start-i18n-intlayer/src/content/index.content.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/$.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/about.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsxexamples/react/start-i18n-intlayer/src/content/404.content.tsexamples/react/start-i18n-intlayer/src/content/about.content.tsexamples/react/start-i18n-intlayer/src/content/index.content.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
examples/react/start-i18n-intlayer/package.json
🧠 Learnings (7)
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/$.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsxexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
📚 Learning: 2025-09-28T21:41:45.233Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5284
File: e2e/react-start/basic/server.js:50-0
Timestamp: 2025-09-28T21:41:45.233Z
Learning: In Express v5, catch-all routes must use named wildcards. Use `/*splat` to match everything except root path, or `/{*splat}` (with braces) to match including root path. The old `*` syntax is not allowed and will cause "Missing parameter name" errors. This breaking change requires explicit naming of wildcard parameters.
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/$.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/about.tsx
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/package.json : Use workspace protocol `workspace:*` for internal dependencies in package.json files
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-i18n-intlayer/package.jsonexamples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx
🧬 Code graph analysis (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/about.tsx (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/index.tsx (1)
Route(7-17)examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
Route(13-34)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
Route(13-34)examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
LocalizedLink(39-52)
🔇 Additional comments (8)
examples/react/start-i18n-intlayer/src/content/about.content.ts (1)
1-19: Clean, consistent Intlayer dictionary module. Looks aligned withuseIntlayer('about')usage andsatisfies Dictionaryenforcement.examples/react/start-i18n-intlayer/src/content/404.content.ts (1)
1-29: LGTM: well-structurednot-founddictionary. Keys and translations are straightforward and consistent with the example’s pattern.examples/react/start-i18n-intlayer/src/content/index.content.tsx (1)
1-14: LGTM: minimalappdictionary with proper typing.examples/react/start-i18n-intlayer/src/routes/{-$locale}/$.tsx (1)
1-8: Nice and minimal catch-all that reuses the localized 404 component.examples/react/start-i18n-intlayer/src/routes/{-$locale}/about.tsx (1)
1-17: LGTM: route is correctly wired touseIntlayer('about')and renders expected content.examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
36-50: Double-checkuseLocale()/useI18nHTMLAttributes()behavior when called beforeIntlayerProvider. (Line 37, Line 40)If these hooks rely on provider context, consider deriving
defaultLocale/attributes from non-hook config or moving the calls under a provider that’s guaranteed to exist.Also applies to: 53-62
examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx (2)
1-4: LGTM!The imports are clean and necessary for the 404 route functionality.
6-8: LGTM!The route definition correctly sets up the locale-aware 404 route.
examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx
Outdated
Show resolved
Hide resolved
|
PR updated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
examples/react/start-i18n-intlayer/eslint.config.ts (1)
1-14: Add the repo-required “router” ESLint plugin rules to this config (currently missing).
Right now this composes core/TS/perfectionist, but it doesn’t apply the router best-practices rules required for**/*.{js,ts,tsx}. As per coding guidelines, please wire in the router ESLint plugin’s recommended rules (flat config), and ensure it’s installed indevDependencies.import eslint from '@eslint/js' import perfectionist from 'eslint-plugin-perfectionist' import { defineConfig } from 'eslint/config' +// TODO: confirm correct package name + flat-config export for TanStack Router’s ESLint plugin +// import router from 'eslint-plugin-router' import tseslint from 'typescript-eslint' export default defineConfig( { - ignores: ['.intlayer/**', '.tanstack/**'], + ignores: [ + '.intlayer/**', + '.tanstack/**', + // Avoid linting generated artifacts (common in TanStack Router examples) + '**/routeTree.gen.*', + '.output/**', + ], }, eslint.configs.recommended, tseslint.configs.strict, tseslint.configs.stylistic, perfectionist.configs['recommended-alphabetical'], + // router.configs.recommended, )TanStack Router ESLint plugin: what is the correct npm package name and (flat) recommended config export to enable “router best practices” rules?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
examples/react/start-i18n-intlayer/eslint.config.ts(1 hunks)examples/react/start-i18n-intlayer/package.json(1 hunks)examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
examples/react/start-i18n-intlayer/package.json
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
examples/react/start-i18n-intlayer/eslint.config.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
examples/react/start-i18n-intlayer/eslint.config.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx
🧠 Learnings (5)
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-i18n-intlayer/package.jsonexamples/react/start-i18n-intlayer/eslint.config.tsexamples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-i18n-intlayer/package.jsonexamples/react/start-i18n-intlayer/eslint.config.ts
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code
Applied to files:
examples/react/start-i18n-intlayer/package.jsonexamples/react/start-i18n-intlayer/eslint.config.ts
🧬 Code graph analysis (1)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/route.tsx (1)
Route(13-34)examples/react/start-i18n-intlayer/src/components/localized-link.tsx (1)
LocalizedLink(39-52)
🔇 Additional comments (2)
examples/react/start-i18n-intlayer/src/routes/{-$locale}/404.tsx (2)
1-8: LGTM! Route definition follows router best practices.The imports are appropriate and the file route is correctly defined with the locale-aware path pattern
/{-$locale}/404, which aligns with the parent route's locale validation logic.
10-49: Excellent implementation of the localized 404 page!The component correctly integrates i18n via
useIntlayer, uses semantic HTML for good baseline accessibility, and employsLocalizedLinkfor proper locale-aware navigation. The Tailwind styling creates a polished, modern 404 experience with decorative elements that don't interfere with interaction (pointer-events-none). All classes are valid and the previousbg-gradient-to-btypo has been resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
examples/react/start-i18n-intlayer/package.json (1)
28-42: DevDependencies are reasonable; consider adding atypecheckscript (optional).
If other examples/documentation expect it, adding"typecheck": "tsc -p tsconfig.json --noEmit"can make CI/local checks more consistent.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
examples/react/start-i18n-intlayer/package.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
examples/react/start-i18n-intlayer/package.json
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-i18n-intlayer/package.json
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code
Applied to files:
examples/react/start-i18n-intlayer/package.json
🔇 Additional comments (1)
examples/react/start-i18n-intlayer/package.json (1)
5-14: Scripts are in good shape (lint present, start/serve separation is clear).
Nice to seelintincluded alongsidetestand the editor helper script.
This PR includes an example showing how to internationalize a TanStack Start / Router app using Intlayer
It includes i18n for:
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.