-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
add paraglide examples #5256
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
add paraglide examples #5256
Conversation
WalkthroughAdds three React example apps demonstrating Paraglide JS with TanStack Router and TanStack Start. Introduces scaffolding (configs, manifests, Tailwind), i18n message bundles (en/de), Vite plugins with URL localization, router wiring with input/output rewrites, route trees and components, SSR middleware, prerender config, and documentation. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant B as Browser
participant R as TanStack Router
participant RW as Rewrite (deLocalize/localize)
participant RT as Routes (beforeLoad)
B->>R: Navigate to URL (/de/ueber)
R->>RW: Input rewrite (deLocalizeUrl)
RW-->>R: Canonical URL (/about)
R->>RT: Match route + beforeLoad
RT-->>R: optional redirect URL?
alt Redirect needed
R-->>B: Throw redirect to localized URL
else No redirect
R->>RW: Output rewrite (localizeUrl)
RW-->>R: Localized URL (/de/ueber)
R-->>B: Render route component
end
sequenceDiagram
autonumber
participant C as Client
participant S as Server Entry
participant PM as paraglideMiddleware
participant H as handler.fetch
C->>S: HTTP Request (/de/ueber)
S->>PM: fetch(req)
PM->>H: Forward with de-localized URL (/about)
H-->>PM: Response
PM-->>S: Response (headers/URL localized as needed)
S-->>C: HTTP Response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 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 |
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: 16
🧹 Nitpick comments (14)
examples/react/18n-paraglide/messages/de.json (1)
4-6: Normalize the umlautThe string on Line 6 uses a combining diaeresis (
Ü) instead of the precomposedÜ, which can render oddly and break strict string comparisons. Prefer the canonical character.- "about_page": "Über uns" + "about_page": "Über uns"examples/react/start-i18n-paraglide/README.md (1)
1-1: Docs polish: typos, tabs, and lint fixes
- Line 1: “TanSTack” → “TanStack”.
- Line 3 (MD059): Replace “here” with descriptive link text.
- Lines 22, 25–27, 39–40 (MD010): Replace hard tabs with spaces.
- Line 79: “add change the” → “change the”.
- Line 181: “plguin” → “plugin”.
- Consistency: Prefer including .js extension in ESM imports in snippets (e.g., localizeHref/shouldRedirect).
Apply this minimal diff to address key issues:
-# TanSTack Start example +# TanStack Start example -This example shows how to use Paraglide with TanStack Start. The source code can be found [here](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-start). +This example shows how to use Paraglide with TanStack Start. See the source code in the Paraglide + TanStack Start example repository: https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-start - plugins: [ + plugins: [ tanstackStart(), react(), - paraglideVitePlugin({ - project: "./project.inlang", - outdir: "./app/paraglide", + paraglideVitePlugin({ + project: "./project.inlang", + outdir: "./app/paraglide", outputStructure: "message-modules", cookieName: "PARAGLIDE_LOCALE", strategy: ["url", "cookie", "preferredLanguage", "baseLocale"], urlPatterns: [ { pattern: "/:path(.*)?", localized: [ ["en", "/en/:path(.*)?"], ], }, ], - }), - ], + }), + ], }); -In `__root.tsx` add change the html lang attribute to the current locale. +In `__root.tsx`, change the html lang attribute to the current locale. -import { shouldRedirect } from "../paraglide/runtime"; +import { shouldRedirect } from "../paraglide/runtime.js"; -And import into the Paraglide Vite plguin. +And import into the Paraglide Vite plugin.Also applies to: 3-3, 22-22, 25-27, 39-40, 79-79, 181-181
examples/react/start-i18n-paraglide/src/utils/prerender.ts (1)
1-8: Consider adding type safety for route paths.While the implementation is correct, consider defining route paths as constants or using a type-safe approach to prevent typos and ensure consistency with the actual routes.
import { localizeHref } from "../paraglide/runtime"; -export const prerenderRoutes = ["/", "/about"].map((path) => ({ +const PRERENDERABLE_PATHS = ["/", "/about"] as const; + +export const prerenderRoutes = PRERENDERABLE_PATHS.map((path) => ({ path: localizeHref(path), prerender: { enabled: true, }, }));This approach provides better maintainability and makes it easier to track which routes are prerendered.
examples/react/18n-paraglide/src/routes/__root.tsx (2)
16-24: Consider error handling for the redirect logic.The
beforeLoadhook throws a redirect but doesn't handle potential errors fromshouldRedirect. Consider wrapping in a try-catch for robustness.beforeLoad: async () => { document.documentElement.setAttribute("lang", getLocale()); - const decision = await shouldRedirect({ url: window.location.href }); - - if (decision.redirectUrl) { - throw redirect({ href: decision.redirectUrl.href }); + try { + const decision = await shouldRedirect({ url: window.location.href }); + + if (decision.redirectUrl) { + throw redirect({ href: decision.redirectUrl.href }); + } + } catch (error) { + // If it's a redirect, re-throw it + if (error && typeof error === 'object' && 'href' in error) { + throw error; + } + // Log other errors but don't block navigation + console.error('Error checking redirect:', error); } },
50-59: Consider adding ARIA labels for better accessibility.The locale switcher buttons should have ARIA labels to improve screen reader support.
{locales.map((locale) => ( <button key={locale} onClick={() => setLocale(locale)} data-active-locale={locale === getLocale()} + aria-label={`Switch to ${locale} language`} + aria-pressed={locale === getLocale()} className="rounded p-1 px-2 border border-gray-300 cursor-pointer [&[data-active-locale=true]]:bg-gray-500 [&[data-active-locale=true]]:text-white" > {locale} </button> ))}examples/react/start-i18n-paraglide/vite.config.ts (2)
9-37: Load tsconfig paths plugin first.Put
viteTsConfigPaths()at the start so path resolution is available to subsequent plugins during their config and transform hooks.Apply this diff:
plugins: [ - paraglideVitePlugin({ + viteTsConfigPaths(), + paraglideVitePlugin({ project: "./project.inlang", @@ - viteTsConfigPaths(), tanstackStart(), viteReact(), tailwindcss(), ],
10-31: Optional: Add explicit root pattern for clarity.Your catch-all will cover “/”, but adding an explicit root mapping makes intent clearer and avoids edge cases.
Apply this diff:
urlPatterns: [ + { + pattern: "/", + localized: [ + ["en", "/en"], + ["de", "/de"], + ], + }, { pattern: "/about",examples/react/i18n-paraglide/src/main.tsx (1)
31-39: Hydrate when SSR markup exists; create root otherwise.Prevents a non-interactive page if markup was server-rendered.
Apply this diff:
-const rootElement = document.getElementById("app"); -if (rootElement && !rootElement.innerHTML) { - const root = ReactDOM.createRoot(rootElement); - root.render( - <StrictMode> - <RouterProvider router={router} /> - </StrictMode> - ); -} +const rootElement = document.getElementById("app"); +if (rootElement) { + const app = ( + <StrictMode> + <RouterProvider router={router} /> + </StrictMode> + ); + if (rootElement.innerHTML) { + ReactDOM.hydrateRoot(rootElement, app); + } else { + ReactDOM.createRoot(rootElement).render(app); + } +}examples/react/18n-paraglide/vite.config.ts (1)
4-4: Same ESM-safe alias fix applies here.Avoid
__dirnamein ESM contexts; usefileURLToPath.Apply this diff:
-import { resolve } from "node:path"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; @@ -export default defineConfig({ +const __dirname = dirname(fileURLToPath(import.meta.url)); +export default defineConfig({ @@ - "@": resolve(__dirname, "./src"), + "@": resolve(__dirname, "src"),Also applies to: 45-47
examples/react/start-i18n-paraglide/src/routes/__root.tsx (2)
80-90: Gate devtools to development builds.Avoid shipping devtools in production.
Apply this diff:
- <TanstackDevtools - config={{ - position: "bottom-left", - }} - plugins={[ - { - name: "Tanstack Router", - render: <TanStackRouterDevtoolsPanel />, - }, - ]} - /> + {import.meta.env.DEV && ( + <TanstackDevtools + config={{ position: "bottom-left" }} + plugins={[ + { + name: "Tanstack Router", + render: <TanStackRouterDevtoolsPanel />, + }, + ]} + /> + )}
63-71: Improve a11y on locale toggle buttons.Expose state with
aria-pressedand add an accessible label.Apply this diff:
- <button + <button key={locale} onClick={() => setLocale(locale)} data-active-locale={locale === getLocale()} - className="rounded p-1 px-2 border border-gray-300 cursor-pointer [&[data-active-locale=true]]:bg-gray-500 [&[data-active-locale=true]]:text-white" + aria-pressed={locale === getLocale()} + aria-label={`Switch language to ${locale}`} + className="rounded p-1 px-2 border border-gray-300 cursor-pointer [&[data-active-locale=true]]:bg-gray-500 [&[data-active-locale=true]]:text-white" > {locale} </button>examples/react/i18n-paraglide/src/routes/__root.tsx (2)
16-24: Ensure proper async handling in beforeLoad.The implementation correctly handles the redirect decision, but consider adding error handling for the
shouldRedirectcall.Consider adding error handling:
beforeLoad: async () => { document.documentElement.setAttribute("lang", getLocale()); - const decision = await shouldRedirect({ url: window.location.href }); - - if (decision.redirectUrl) { - throw redirect({ href: decision.redirectUrl.href }); + try { + const decision = await shouldRedirect({ url: window.location.href }); + + if (decision.redirectUrl) { + throw redirect({ href: decision.redirectUrl.href }); + } + } catch (error) { + // Only rethrow if it's a redirect, otherwise log and continue + if (error instanceof redirect) { + throw error; + } + console.error('Failed to check redirect decision:', error); } },
50-60: Consider accessibility improvements for locale switcher.The locale switcher buttons should have aria-labels for better screen reader support and keyboard navigation improvements.
Add accessibility attributes:
{locales.map((locale) => ( <button key={locale} onClick={() => setLocale(locale)} data-active-locale={locale === getLocale()} + aria-label={`Switch language to ${locale}`} + aria-pressed={locale === getLocale()} className="rounded p-1 px-2 border border-gray-300 cursor-pointer [&[data-active-locale=true]]:bg-gray-500 [&[data-active-locale=true]]:text-white" > {locale} </button> ))}examples/react/start-i18n-paraglide/src/routes/index.tsx (1)
6-10: Use Zod for emoji validation
Leverage a Zod schema in theinputValidatorfor composable, reusable validation:import { z } from 'zod'; const getServerMessage = createServerFn() .inputValidator(z.string().regex(/^\p{Emoji}+$/u, 'Invalid emoji')) .handler(ctx => m.server_message({ emoji: ctx.data }));
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (12)
examples/react/18n-paraglide/public/favicon.icois excluded by!**/*.icoexamples/react/18n-paraglide/public/logo192.pngis excluded by!**/*.pngexamples/react/18n-paraglide/public/logo512.pngis excluded by!**/*.pngexamples/react/18n-paraglide/src/logo.svgis excluded by!**/*.svgexamples/react/i18n-paraglide/public/favicon.icois excluded by!**/*.icoexamples/react/i18n-paraglide/public/logo192.pngis excluded by!**/*.pngexamples/react/i18n-paraglide/public/logo512.pngis excluded by!**/*.pngexamples/react/i18n-paraglide/src/logo.svgis excluded by!**/*.svgexamples/react/start-i18n-paraglide/public/favicon.icois excluded by!**/*.icoexamples/react/start-i18n-paraglide/public/logo192.pngis excluded by!**/*.pngexamples/react/start-i18n-paraglide/public/logo512.pngis excluded by!**/*.pngexamples/react/start-i18n-paraglide/src/logo.svgis excluded by!**/*.svg
📒 Files selected for processing (64)
examples/react/18n-paraglide/.gitignore(1 hunks)examples/react/18n-paraglide/.vscode/settings.json(1 hunks)examples/react/18n-paraglide/README.md(1 hunks)examples/react/18n-paraglide/index.html(1 hunks)examples/react/18n-paraglide/messages/de.json(1 hunks)examples/react/18n-paraglide/messages/en.json(1 hunks)examples/react/18n-paraglide/package.json(1 hunks)examples/react/18n-paraglide/project.inlang/.gitignore(1 hunks)examples/react/18n-paraglide/project.inlang/project_id(1 hunks)examples/react/18n-paraglide/project.inlang/settings.json(1 hunks)examples/react/18n-paraglide/public/manifest.json(1 hunks)examples/react/18n-paraglide/public/robots.txt(1 hunks)examples/react/18n-paraglide/src/main.tsx(1 hunks)examples/react/18n-paraglide/src/routeTree.gen.ts(1 hunks)examples/react/18n-paraglide/src/routes/__root.tsx(1 hunks)examples/react/18n-paraglide/src/routes/about.tsx(1 hunks)examples/react/18n-paraglide/src/routes/index.tsx(1 hunks)examples/react/18n-paraglide/src/styles.css(1 hunks)examples/react/18n-paraglide/tsconfig.json(1 hunks)examples/react/18n-paraglide/vite.config.ts(1 hunks)examples/react/i18n-paraglide/.gitignore(1 hunks)examples/react/i18n-paraglide/.vscode/settings.json(1 hunks)examples/react/i18n-paraglide/README.md(1 hunks)examples/react/i18n-paraglide/index.html(1 hunks)examples/react/i18n-paraglide/messages/de.json(1 hunks)examples/react/i18n-paraglide/messages/en.json(1 hunks)examples/react/i18n-paraglide/package.json(1 hunks)examples/react/i18n-paraglide/project.inlang/.gitignore(1 hunks)examples/react/i18n-paraglide/project.inlang/project_id(1 hunks)examples/react/i18n-paraglide/project.inlang/settings.json(1 hunks)examples/react/i18n-paraglide/public/manifest.json(1 hunks)examples/react/i18n-paraglide/public/robots.txt(1 hunks)examples/react/i18n-paraglide/src/main.tsx(1 hunks)examples/react/i18n-paraglide/src/routeTree.gen.ts(1 hunks)examples/react/i18n-paraglide/src/routes/__root.tsx(1 hunks)examples/react/i18n-paraglide/src/routes/about.tsx(1 hunks)examples/react/i18n-paraglide/src/routes/index.tsx(1 hunks)examples/react/i18n-paraglide/src/styles.css(1 hunks)examples/react/i18n-paraglide/tsconfig.json(1 hunks)examples/react/i18n-paraglide/vite.config.ts(1 hunks)examples/react/start-i18n-paraglide/.gitignore(1 hunks)examples/react/start-i18n-paraglide/.vscode/extensions.json(1 hunks)examples/react/start-i18n-paraglide/.vscode/settings.json(1 hunks)examples/react/start-i18n-paraglide/README.md(1 hunks)examples/react/start-i18n-paraglide/messages/de.json(1 hunks)examples/react/start-i18n-paraglide/messages/en.json(1 hunks)examples/react/start-i18n-paraglide/package.json(1 hunks)examples/react/start-i18n-paraglide/project.inlang/.gitignore(1 hunks)examples/react/start-i18n-paraglide/project.inlang/project_id(1 hunks)examples/react/start-i18n-paraglide/project.inlang/settings.json(1 hunks)examples/react/start-i18n-paraglide/public/manifest.json(1 hunks)examples/react/start-i18n-paraglide/public/robots.txt(1 hunks)examples/react/start-i18n-paraglide/src/routeTree.gen.ts(1 hunks)examples/react/start-i18n-paraglide/src/router.tsx(1 hunks)examples/react/start-i18n-paraglide/src/routes/__root.tsx(1 hunks)examples/react/start-i18n-paraglide/src/routes/about.tsx(1 hunks)examples/react/start-i18n-paraglide/src/routes/index.tsx(1 hunks)examples/react/start-i18n-paraglide/src/server.ts(1 hunks)examples/react/start-i18n-paraglide/src/styles.css(1 hunks)examples/react/start-i18n-paraglide/src/utils/prerender.ts(1 hunks)examples/react/start-i18n-paraglide/src/utils/seo.ts(1 hunks)examples/react/start-i18n-paraglide/src/utils/translated-pathnames.ts(1 hunks)examples/react/start-i18n-paraglide/tsconfig.json(1 hunks)examples/react/start-i18n-paraglide/vite.config.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
examples/{react,solid}/**
📄 CodeRabbit inference engine (AGENTS.md)
Keep example applications under examples/react/ and examples/solid/
Files:
examples/react/18n-paraglide/index.htmlexamples/react/18n-paraglide/project.inlang/settings.jsonexamples/react/start-i18n-paraglide/public/manifest.jsonexamples/react/18n-paraglide/src/styles.cssexamples/react/18n-paraglide/messages/en.jsonexamples/react/i18n-paraglide/tsconfig.jsonexamples/react/start-i18n-paraglide/tsconfig.jsonexamples/react/18n-paraglide/project.inlang/project_idexamples/react/i18n-paraglide/messages/en.jsonexamples/react/start-i18n-paraglide/project.inlang/project_idexamples/react/18n-paraglide/vite.config.tsexamples/react/i18n-paraglide/project.inlang/project_idexamples/react/18n-paraglide/public/robots.txtexamples/react/i18n-paraglide/src/routeTree.gen.tsexamples/react/start-i18n-paraglide/project.inlang/settings.jsonexamples/react/start-i18n-paraglide/src/utils/prerender.tsexamples/react/18n-paraglide/tsconfig.jsonexamples/react/18n-paraglide/src/main.tsxexamples/react/start-i18n-paraglide/vite.config.tsexamples/react/start-i18n-paraglide/messages/en.jsonexamples/react/i18n-paraglide/public/manifest.jsonexamples/react/18n-paraglide/src/routes/about.tsxexamples/react/18n-paraglide/src/routes/__root.tsxexamples/react/start-i18n-paraglide/src/utils/translated-pathnames.tsexamples/react/i18n-paraglide/src/routes/index.tsxexamples/react/18n-paraglide/public/manifest.jsonexamples/react/i18n-paraglide/messages/de.jsonexamples/react/18n-paraglide/src/routes/index.tsxexamples/react/i18n-paraglide/project.inlang/settings.jsonexamples/react/start-i18n-paraglide/src/server.tsexamples/react/i18n-paraglide/public/robots.txtexamples/react/start-i18n-paraglide/public/robots.txtexamples/react/start-i18n-paraglide/src/styles.cssexamples/react/18n-paraglide/messages/de.jsonexamples/react/start-i18n-paraglide/src/routes/about.tsxexamples/react/18n-paraglide/README.mdexamples/react/i18n-paraglide/src/styles.cssexamples/react/18n-paraglide/package.jsonexamples/react/i18n-paraglide/package.jsonexamples/react/start-i18n-paraglide/src/router.tsxexamples/react/start-i18n-paraglide/README.mdexamples/react/i18n-paraglide/index.htmlexamples/react/18n-paraglide/src/routeTree.gen.tsexamples/react/i18n-paraglide/README.mdexamples/react/i18n-paraglide/vite.config.tsexamples/react/start-i18n-paraglide/package.jsonexamples/react/start-i18n-paraglide/src/utils/seo.tsexamples/react/start-i18n-paraglide/src/routes/index.tsxexamples/react/i18n-paraglide/src/main.tsxexamples/react/start-i18n-paraglide/src/routes/__root.tsxexamples/react/start-i18n-paraglide/src/routeTree.gen.tsexamples/react/start-i18n-paraglide/messages/de.jsonexamples/react/i18n-paraglide/src/routes/about.tsxexamples/react/i18n-paraglide/src/routes/__root.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript in strict mode with extensive type safety across the codebase
Files:
examples/react/18n-paraglide/vite.config.tsexamples/react/i18n-paraglide/src/routeTree.gen.tsexamples/react/start-i18n-paraglide/src/utils/prerender.tsexamples/react/18n-paraglide/src/main.tsxexamples/react/start-i18n-paraglide/vite.config.tsexamples/react/18n-paraglide/src/routes/about.tsxexamples/react/18n-paraglide/src/routes/__root.tsxexamples/react/start-i18n-paraglide/src/utils/translated-pathnames.tsexamples/react/i18n-paraglide/src/routes/index.tsxexamples/react/18n-paraglide/src/routes/index.tsxexamples/react/start-i18n-paraglide/src/server.tsexamples/react/start-i18n-paraglide/src/routes/about.tsxexamples/react/start-i18n-paraglide/src/router.tsxexamples/react/18n-paraglide/src/routeTree.gen.tsexamples/react/i18n-paraglide/vite.config.tsexamples/react/start-i18n-paraglide/src/utils/seo.tsexamples/react/start-i18n-paraglide/src/routes/index.tsxexamples/react/i18n-paraglide/src/main.tsxexamples/react/start-i18n-paraglide/src/routes/__root.tsxexamples/react/start-i18n-paraglide/src/routeTree.gen.tsexamples/react/i18n-paraglide/src/routes/about.tsxexamples/react/i18n-paraglide/src/routes/__root.tsx
**/src/routes/**
📄 CodeRabbit inference engine (AGENTS.md)
Place file-based routes under src/routes/ directories
Files:
examples/react/18n-paraglide/src/routes/about.tsxexamples/react/18n-paraglide/src/routes/__root.tsxexamples/react/i18n-paraglide/src/routes/index.tsxexamples/react/18n-paraglide/src/routes/index.tsxexamples/react/start-i18n-paraglide/src/routes/about.tsxexamples/react/start-i18n-paraglide/src/routes/index.tsxexamples/react/start-i18n-paraglide/src/routes/__root.tsxexamples/react/i18n-paraglide/src/routes/about.tsxexamples/react/i18n-paraglide/src/routes/__root.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace:* protocol for internal dependencies in package.json files
Files:
examples/react/18n-paraglide/package.jsonexamples/react/i18n-paraglide/package.jsonexamples/react/start-i18n-paraglide/package.json
🧠 Learnings (2)
📚 Learning: 2025-09-23T17:36:12.598Z
Learnt from: CR
PR: TanStack/router#0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript in strict mode with extensive type safety across the codebase
Applied to files:
examples/react/i18n-paraglide/tsconfig.jsonexamples/react/start-i18n-paraglide/tsconfig.jsonexamples/react/18n-paraglide/tsconfig.json
📚 Learning: 2025-09-23T17:36:12.598Z
Learnt from: CR
PR: TanStack/router#0
File: AGENTS.md:0-0
Timestamp: 2025-09-23T17:36:12.598Z
Learning: Applies to packages/{react-router,solid-router}/** : Implement React and Solid bindings/components only in packages/react-router/ and packages/solid-router/
Applied to files:
examples/react/18n-paraglide/src/main.tsxexamples/react/18n-paraglide/src/routes/__root.tsxexamples/react/i18n-paraglide/src/main.tsxexamples/react/start-i18n-paraglide/src/routes/__root.tsxexamples/react/i18n-paraglide/src/routes/__root.tsx
🧬 Code graph analysis (15)
examples/react/18n-paraglide/src/main.tsx (1)
e2e/react-router/js-only-file-based/src/main.jsx (2)
rootElement(15-15)root(18-18)
examples/react/18n-paraglide/src/routes/about.tsx (2)
examples/react/18n-paraglide/src/routes/__root.tsx (1)
Route(15-70)examples/react/18n-paraglide/src/routes/index.tsx (1)
Route(4-6)
examples/react/18n-paraglide/src/routes/__root.tsx (1)
examples/react/i18n-paraglide/src/routes/__root.tsx (1)
Route(15-70)
examples/react/start-i18n-paraglide/src/utils/translated-pathnames.ts (1)
examples/react/start-i18n-paraglide/src/routeTree.gen.ts (1)
FileRoutesByTo(30-33)
examples/react/i18n-paraglide/src/routes/index.tsx (3)
examples/react/i18n-paraglide/src/routes/__root.tsx (1)
Route(15-70)examples/react/i18n-paraglide/src/routes/about.tsx (1)
Route(4-6)examples/react/start-i18n-paraglide/src/routes/index.tsx (1)
Route(12-21)
examples/react/18n-paraglide/src/routes/index.tsx (2)
examples/react/18n-paraglide/src/routes/__root.tsx (1)
Route(15-70)examples/react/18n-paraglide/src/routes/about.tsx (1)
Route(4-6)
examples/react/start-i18n-paraglide/src/routes/about.tsx (2)
examples/react/start-i18n-paraglide/src/routes/__root.tsx (1)
Route(13-31)examples/react/start-i18n-paraglide/src/routes/index.tsx (1)
Route(12-21)
examples/react/18n-paraglide/src/routeTree.gen.ts (2)
examples/react/i18n-paraglide/src/routeTree.gen.ts (6)
FileRoutesByFullPath(26-29)FileRoutesByTo(30-33)FileRoutesById(34-38)FileRouteTypes(39-46)RootRouteChildren(47-50)routeTree(75-77)examples/react/start-i18n-paraglide/src/routeTree.gen.ts (6)
FileRoutesByFullPath(26-29)FileRoutesByTo(30-33)FileRoutesById(34-38)FileRouteTypes(39-46)RootRouteChildren(47-50)routeTree(75-77)
examples/react/start-i18n-paraglide/src/utils/seo.ts (1)
scripts/llms-generate.mjs (1)
title(96-96)
examples/react/start-i18n-paraglide/src/routes/index.tsx (2)
examples/react/i18n-paraglide/src/routes/index.tsx (1)
Route(4-6)examples/react/start-i18n-paraglide/src/routes/__root.tsx (1)
Route(13-31)
examples/react/i18n-paraglide/src/main.tsx (1)
e2e/react-router/js-only-file-based/src/main.jsx (2)
rootElement(15-15)root(18-18)
examples/react/start-i18n-paraglide/src/routes/__root.tsx (3)
examples/react/i18n-paraglide/src/routes/__root.tsx (1)
Route(15-70)examples/react/start-i18n-paraglide/src/routes/index.tsx (1)
Route(12-21)packages/react-router-devtools/src/TanStackRouterDevtoolsPanel.tsx (1)
TanStackRouterDevtoolsPanel(37-87)
examples/react/start-i18n-paraglide/src/routeTree.gen.ts (1)
examples/react/start-i18n-paraglide/src/router.tsx (1)
getRouter(8-18)
examples/react/i18n-paraglide/src/routes/about.tsx (2)
examples/react/i18n-paraglide/src/routes/__root.tsx (1)
Route(15-70)examples/react/i18n-paraglide/src/routes/index.tsx (1)
Route(4-6)
examples/react/i18n-paraglide/src/routes/__root.tsx (2)
examples/react/i18n-paraglide/src/routes/about.tsx (1)
Route(4-6)examples/react/i18n-paraglide/src/routes/index.tsx (1)
Route(4-6)
🪛 markdownlint-cli2 (0.18.1)
examples/react/18n-paraglide/README.md
3-3: Link text should be descriptive
(MD059, descriptive-link-text)
22-22: Hard tabs
Column: 1
(MD010, no-hard-tabs)
25-25: Hard tabs
Column: 2
(MD010, no-hard-tabs)
26-26: Hard tabs
Column: 2
(MD010, no-hard-tabs)
27-27: Hard tabs
Column: 2
(MD010, no-hard-tabs)
28-28: Hard tabs
Column: 2
(MD010, no-hard-tabs)
29-29: Hard tabs
Column: 1
(MD010, no-hard-tabs)
examples/react/start-i18n-paraglide/README.md
3-3: Link text should be descriptive
(MD059, descriptive-link-text)
22-22: Hard tabs
Column: 1
(MD010, no-hard-tabs)
25-25: Hard tabs
Column: 2
(MD010, no-hard-tabs)
26-26: Hard tabs
Column: 2
(MD010, no-hard-tabs)
27-27: Hard tabs
Column: 2
(MD010, no-hard-tabs)
39-39: Hard tabs
Column: 2
(MD010, no-hard-tabs)
40-40: Hard tabs
Column: 1
(MD010, no-hard-tabs)
examples/react/i18n-paraglide/README.md
3-3: Link text should be descriptive
(MD059, descriptive-link-text)
22-22: Hard tabs
Column: 1
(MD010, no-hard-tabs)
25-25: Hard tabs
Column: 2
(MD010, no-hard-tabs)
26-26: Hard tabs
Column: 2
(MD010, no-hard-tabs)
27-27: Hard tabs
Column: 2
(MD010, no-hard-tabs)
28-28: Hard tabs
Column: 2
(MD010, no-hard-tabs)
29-29: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🔇 Additional comments (64)
examples/react/start-i18n-paraglide/public/robots.txt (1)
1-3: Robots directives look goodAllow-all directives are appropriate for the public demo assets.
examples/react/18n-paraglide/src/styles.css (1)
1-1: Tailwind import looks goodImporting Tailwind via
@import "tailwindcss";aligns with the new Tailwind setup in this example. No issues spotted.examples/react/start-i18n-paraglide/public/manifest.json (1)
1-25: LGTM!Manifest fields look consistent with the new example app; no issues spotted.
examples/react/18n-paraglide/project.inlang/.gitignore (1)
1-1: Cache ignore entry LGTMIgnoring the generated Inlang cache prevents churn in the repo.
examples/react/start-i18n-paraglide/project.inlang/project_id (1)
1-1: Project ID addition looks goodCapturing the Inlang project identifier here keeps the configuration consistent.
examples/react/start-i18n-paraglide/src/styles.css (1)
1-1: Tailwind import wired correctlyThe stylesheet now delegates to Tailwind’s entrypoint, matching the plugin setup in this example.
examples/react/start-i18n-paraglide/.vscode/extensions.json (1)
1-5: Helpful editor recommendationAdding the inlang VS Code extension as a recommendation improves the DX for this example.
examples/react/i18n-paraglide/project.inlang/.gitignore (1)
1-1: Cache artifacts excludedGood call ignoring the Inlang cache directory for this project.
examples/react/i18n-paraglide/.gitignore (1)
1-9: Comprehensive ignore listThese entries cover the usual build and local artifacts for the example app.
examples/react/18n-paraglide/project.inlang/project_id (1)
1-1: Inlang project ID capturedStoring the generated project ID ensures the tooling can resolve this example’s resources.
examples/react/start-i18n-paraglide/project.inlang/.gitignore (1)
1-1: Cache ignore entry LGTMSame rationale here—keeps transient cache data out of version control.
examples/react/18n-paraglide/.gitignore (1)
1-9: Good call ignoring generated clutterIgnoring build artifacts, environment files, and the
.tanstackcache will keep example diffs clean and reproducible. Nice touch.examples/react/i18n-paraglide/src/styles.css (1)
1-1: Confirm Tailwind version compatibility
@import "tailwindcss";only compiles with the Tailwind v4+ pipeline. If this example is still pinned to Tailwind v3.x (or if consumers copy the setup without the v4 preview), the build will drop all utility classes. Please confirm the packages are aligned, or revert to the v3-style@tailwind base/components/utilitiesdirectives.examples/react/start-i18n-paraglide/.vscode/settings.json (1)
1-10: Nice safeguard for generated route treesMarking
routeTree.gen.tsas excluded and readonly prevents accidental edits while keeping file-watchers quiet. Solid developer-experience improvement.examples/react/i18n-paraglide/public/robots.txt (1)
1-3: Robots defaults look goodAllowing all crawlers with an empty disallow block is the right default for an example app.
examples/react/18n-paraglide/.vscode/settings.json (1)
1-10: Consistent tooling configurationSame exclusion/read-only treatment here keeps the generated route tree in sync across examples. 👍
examples/react/i18n-paraglide/public/manifest.json (1)
1-25: Manifest wiring looks standardMetadata, icons, and display settings line up with the rest of the scaffold. No issues spotted.
examples/react/start-i18n-paraglide/.gitignore (1)
1-10: Mirroring ignore rulesMatching ignore patterns with the other example keeps all the generated bits out of Git. Looks good.
examples/react/18n-paraglide/package.json (1)
13-27: Switch TanStack deps toworkspace:*.Repo guidelines require internal TanStack packages to use the
workspace:*protocol so examples stay in lockstep with the monorepo builds. Please update the dependency versions accordingly.
[suggest_essential_refactor]
Apply this diff:- "@tanstack/react-router": "^1.132.2", - "@tanstack/router-plugin": "^1.132.3", + "@tanstack/react-router": "workspace:*", + "@tanstack/router-plugin": "workspace:*",As per coding guidelines
examples/react/i18n-paraglide/package.json (1)
13-27: Switch TanStack deps toworkspace:*.Same as the other example, the internal TanStack packages should reference the local workspace to avoid version skew.
[suggest_essential_refactor]
Apply this diff:- "@tanstack/react-router": "^1.132.2", - "@tanstack/router-plugin": "^1.132.3", + "@tanstack/react-router": "workspace:*", + "@tanstack/router-plugin": "workspace:*",As per coding guidelines
examples/react/start-i18n-paraglide/package.json (1)
12-27: Switch TanStack deps toworkspace:*.Please align the example with the monorepo policy by pointing TanStack dependencies at the workspace.
[suggest_essential_refactor]
Apply this diff:- "@tanstack/react-router": "^1.132.7", - "@tanstack/react-start": "^1.132.9", + "@tanstack/react-router": "workspace:*", + "@tanstack/react-start": "workspace:*",As per coding guidelines
examples/react/i18n-paraglide/README.md (1)
3-29: Tidy markdown per lint warnings.Markdown lint flagged the generic “here” link text and hard tabs in the Vite diff. Switching to descriptive link text and spaces clears those warnings.
[suggest_optional_refactor]
Apply this diff:-This example shows how to use Paraglide with TanStack Router. The source code can be found [here](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router). +This example shows how to use Paraglide with TanStack Router. The source code can be found in the [official Paraglide TanStack Router example](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router). @@ -export default defineConfig({ - plugins: [ - tanstackRouter({ target: 'react', autoCodeSplitting: true }), - react(), - paraglideVitePlugin({ - project: "./project.inlang", - outdir: "./app/paraglide", - }), - ], +export default defineConfig({ + plugins: [ + tanstackRouter({ target: 'react', autoCodeSplitting: true }), + react(), + paraglideVitePlugin({ + project: "./project.inlang", + outdir: "./app/paraglide", + }), + ],examples/react/start-i18n-paraglide/src/server.ts (1)
4-8: Server middleware wiring looks correctParaglide middleware is properly wrapping the Start handler; import extensions align with ESM.
examples/react/18n-paraglide/tsconfig.json (1)
14-15: Good: verbatimModuleSyntax already enabledThis matches recommended ESM/bundler settings and the repo’s strict TS stance.
examples/react/start-i18n-paraglide/messages/en.json (1)
1-8: LGTM: valid Paraglide message schema and keysKeys and placeholders look consistent; JSON is valid.
examples/react/start-i18n-paraglide/src/utils/translated-pathnames.ts (1)
47-56: Example data aligns with route treeThe mappings for "/" and "/about" look correct for en/de.
examples/react/18n-paraglide/public/robots.txt (1)
1-3: LGTM: permissive robots.txt for examplesStandard config; fine for an example app.
examples/react/i18n-paraglide/messages/en.json (1)
1-7: LGTM: valid schema and message keysConsistent with the de bundle and example routes’ usage.
examples/react/i18n-paraglide/project.inlang/settings.json (1)
1-15: LGTM! Inlang configuration follows expected patterns.The Inlang settings correctly configure the i18n setup with proper locale definitions and plugin references.
examples/react/start-i18n-paraglide/src/routes/about.tsx (1)
1-10: LGTM! Clean route implementation with proper i18n integration.The route follows TanStack Router conventions and correctly uses the Paraglide messages for localization.
examples/react/i18n-paraglide/src/routes/about.tsx (1)
1-10: LGTM! Consistent with the example's i18n pattern.The route properly integrates with Paraglide messages and follows the file-based routing pattern.
examples/react/18n-paraglide/src/main.tsx (3)
10-22: LGTM! Router configuration with URL rewriting for i18n.The router setup correctly implements URL localization/delocalization using Paraglide's runtime utilities.
25-29: LGTM! Proper TypeScript module augmentation.The module augmentation correctly registers the router instance for type safety across the application.
32-40: LGTM! Safe client-side rendering check.The rendering logic properly checks for both element existence and prevents hydration mismatches by verifying the element is empty.
examples/react/18n-paraglide/src/routes/index.tsx (1)
1-18: LGTM! Clean route implementation with parameterized i18n message.The component correctly demonstrates passing dynamic parameters to localized messages.
examples/react/18n-paraglide/messages/en.json (1)
1-7: LGTM! Well-structured English message definitions.The JSON structure follows Inlang's message format schema and provides clear message keys with appropriate parameterization.
examples/react/i18n-paraglide/vite.config.ts (1)
9-43: Config looks solid.Plugin order and Paraglide urlPatterns (with catch-all last) look good. Router plugin before React is correct.
examples/react/start-i18n-paraglide/vite.config.ts (1)
1-6: No changes needed:@/*path mapping present in tsconfig.json
Theexamples/react/start-i18n-paraglide/tsconfig.jsonalready defines"paths": { "@/*": ["./src/*"] }.examples/react/start-i18n-paraglide/src/routes/__root.tsx (1)
42-59: No action: rewrite.output is already configured
The router insrc/router.tsxuseslocalizeUrlforrewrite.output, so plain “/” and “/about” links will localize correctly.examples/react/start-i18n-paraglide/src/router.tsx (1)
1-18: LGTM! Clean router setup with i18n URL rewriting.The router configuration correctly integrates Paraglide's URL localization with TanStack Router's rewrite feature. The setup properly handles both input (delocalization) and output (localization) transformations.
examples/react/i18n-paraglide/src/routeTree.gen.ts (1)
1-77: Generated file looks correct.This is an auto-generated file by TanStack Router that properly sets up the route tree with type safety. The file correctly excludes linter/formatter checks as indicated by the comments.
examples/react/18n-paraglide/src/routeTree.gen.ts (6)
1-10: Auto-generated file with proper warnings and linting exclusions.The file includes appropriate warnings about being auto-generated and should not be modified, along with proper linting/formatting exclusions.
11-13: Standard TanStack Router imports for file-based routing.The imports correctly reference the expected route file structure under
./routes/.
15-24: Route definitions follow TanStack Router conventions.The route updates with
id,path, andgetParentRoutefollow the standard pattern for file-based routing in TanStack Router.
26-50: Comprehensive type definitions for route mapping.The interfaces provide proper type safety for the router system, covering all necessary route mapping patterns (by full path, by destination, by ID, and children structure).
52-69: Module augmentation for TanStack Router integration.The module declaration properly extends
@tanstack/react-routerwith file route metadata, enabling type-safe navigation and route resolution.
71-77: Route tree construction follows TanStack Router pattern.The route tree assembly using
_addFileChildrenand_addFileTypesis the standard approach for TanStack Router file-based routing.examples/react/start-i18n-paraglide/src/routeTree.gen.ts (7)
1-10: Auto-generated file with proper warnings and linting exclusions.The file includes appropriate warnings about being auto-generated and should not be modified, along with proper linting/formatting exclusions.
11-13: Standard TanStack Router imports for file-based routing.The imports correctly reference the expected route file structure under
./routes/.
15-24: Route definitions follow TanStack Router conventions.The route updates with
id,path, andgetParentRoutefollow the standard pattern for file-based routing in TanStack Router.
26-50: Comprehensive type definitions for route mapping.The interfaces provide proper type safety for the router system, covering all necessary route mapping patterns (by full path, by destination, by ID, and children structure).
52-69: Module augmentation for TanStack Router integration.The module declaration properly extends
@tanstack/react-routerwith file route metadata, enabling type-safe navigation and route resolution.
71-77: Route tree construction follows TanStack Router pattern.The route tree assembly using
_addFileChildrenand_addFileTypesis the standard approach for TanStack Router file-based routing.
79-86: TanStack Start integration with proper SSR registration.The module augmentation for
@tanstack/react-startcorrectly registers the router type with SSR support enabled, which is appropriate for the Start framework integration.examples/react/i18n-paraglide/.vscode/settings.json (1)
2-10: LGTM on excluding the generated route treeKeeping
routeTree.gen.tsreadonly and invisible to watchers prevents noisy editor churn in this example. Nicely aligned with the other samples.examples/react/i18n-paraglide/tsconfig.json (1)
18-27: Strict TS config looks solidAppreciate that strictness, unused checks, and bundler resolution are all enabled here—it keeps the example consistent with our strict TS guidance. Based on learnings.
examples/react/start-i18n-paraglide/messages/de.json (1)
2-7: German copy looks goodTranslations line up with the keys used elsewhere in the example—no issues spotted.
examples/react/i18n-paraglide/messages/de.json (1)
2-6: Localization entries align with the routesThe localized strings match the route intents (
/ueberetc.), so this resource file checks out.examples/react/i18n-paraglide/project.inlang/project_id (1)
1-1: Project ID recordedLooks like a standard Inlang project id file—nothing to change.
examples/react/start-i18n-paraglide/project.inlang/settings.json (1)
2-14: Inlang settings wired correctlyBase locale, locale list, plugin modules, and path pattern all line up with the message files added in this example. Good to go.
examples/react/18n-paraglide/project.inlang/settings.json (1)
2-14: Duplicate settings stay consistentSame configuration as the Start variant, which keeps the examples aligned—no concerns.
examples/react/18n-paraglide/public/manifest.json (1)
2-24: Manifest metadata checks outIcon set, display mode, and theme colors look standard for the sample PWA manifest.
examples/react/i18n-paraglide/src/routes/index.tsx (1)
4-15: Nice localized home route wiring
createFileRouteand the localized message hook up cleanly. Nothing else needed here.examples/react/18n-paraglide/src/routes/about.tsx (1)
4-9: About route component looks goodStraightforward route component with localized copy—reads well and fits the pattern.
| @@ -0,0 +1,20 @@ | |||
| <!doctype html> | |||
| <html> | |||
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.
Add the <html lang> attribute to meet a11y requirements
The document is missing a lang attribute, so assistive tech can’t determine the page’s language until after hydration updates it. This violates WCAG 3.1.1 on first paint. Please add the default locale (en) here so it’s correct even before JS runs.
-<html>
+<html lang="en">📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <html> | |
| <html lang="en"> |
🤖 Prompt for AI Agents
In examples/react/18n-paraglide/index.html around line 2, the root <html>
element is missing a lang attribute causing accessibility issues on first paint;
update the opening html tag to include lang="en" so the document language is
declared before hydration (use the default locale "en").
| @@ -0,0 +1,141 @@ | |||
| # TanSTack Router example | |||
|
|
|||
| This example shows how to use Paraglide with TanStack Router. The source code can be found [here](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router). | |||
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.
Make the link text more descriptive.
The generic "here" link text isn't accessible or descriptive. Screen reader users need meaningful link text to understand the destination.
Apply this diff to improve the link text:
-This example shows how to use Paraglide with TanStack Router. The source code can be found [here](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router).
+This example shows how to use Paraglide with TanStack Router. The source code can be found in the [Paraglide JS examples repository](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| This example shows how to use Paraglide with TanStack Router. The source code can be found [here](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router). | |
| This example shows how to use Paraglide with TanStack Router. The source code can be found in the [Paraglide JS examples repository](https://github.com/opral/monorepo/tree/main/inlang/packages/paraglide/paraglide-js/examples/tanstack-router). |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
3-3: Link text should be descriptive
(MD059, descriptive-link-text)
🤖 Prompt for AI Agents
In examples/react/18n-paraglide/README.md around line 3, the link text "here" is
non-descriptive and not accessible; update the link text to be meaningful (e.g.,
"Paraglide TanStack Router example source" or "Paraglide + TanStack Router
example repository") so screen readers convey the destination, keeping the
existing URL unchanged.
| export default defineConfig({ | ||
| plugins: [ | ||
| tanstackRouter({ target: 'react', autoCodeSplitting: true }), | ||
| react(), | ||
| + paraglideVitePlugin({ | ||
| + project: "./project.inlang", | ||
| + outdir: "./app/paraglide", | ||
| + }), | ||
| ], |
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.
Fix inconsistent indentation: spaces vs tabs.
The code example mixes tabs and spaces for indentation, which could cause issues when users copy the code.
Apply this diff to use consistent spacing:
export default defineConfig({
- plugins: [
+ plugins: [
tanstackRouter({ target: 'react', autoCodeSplitting: true }),
react(),
-+ paraglideVitePlugin({
-+ project: "./project.inlang",
-+ outdir: "./app/paraglide",
-+ }),
- ],
++ paraglideVitePlugin({
++ project: "./project.inlang",
++ outdir: "./app/paraglide",
++ }),
+ ],
});Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
22-22: Hard tabs
Column: 1
(MD010, no-hard-tabs)
25-25: Hard tabs
Column: 2
(MD010, no-hard-tabs)
26-26: Hard tabs
Column: 2
(MD010, no-hard-tabs)
27-27: Hard tabs
Column: 2
(MD010, no-hard-tabs)
28-28: Hard tabs
Column: 2
(MD010, no-hard-tabs)
29-29: Hard tabs
Column: 1
(MD010, no-hard-tabs)
🤖 Prompt for AI Agents
In examples/react/18n-paraglide/README.md around lines 21 to 29, the code sample
mixes tabs and spaces for indentation; replace tabs with consistent spaces (use
2 spaces to match surrounding file style) so the plugins array lines
(tanstackRouter, react, paraglideVitePlugin block and its options) are indented
uniformly, and ensure the closing brackets align with the same space-based
indentation.
| }); | ||
| ``` | ||
|
|
||
| And import into the Paraglide Vite plguin. |
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.
Fix typo: "plguin" should be "plugin".
There's a typo in the sentence about importing into the Paraglide Vite plugin.
Apply this diff:
-And import into the Paraglide Vite plguin.
+And import into the Paraglide Vite plugin.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| And import into the Paraglide Vite plguin. | |
| And import into the Paraglide Vite plugin. |
🤖 Prompt for AI Agents
In examples/react/18n-paraglide/README.md around line 137, there's a typo:
"plguin" should be corrected to "plugin"; update the sentence to replace
"plguin" with "plugin" so it reads "And import into the Paraglide Vite plugin."
|
|
||
| ## Server side rendering | ||
|
|
||
| For server side rerdering, check out the [TanStack Start guide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs/tanstack-start). |
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.
Fix typo: "rerending" should be "rendering".
There's a typo in the SSR section.
Apply this diff:
-For server side rerending, check out the [TanStack Start guide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs/tanstack-start).
+For server side rendering, check out the [TanStack Start guide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs/tanstack-start).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| For server side rerdering, check out the [TanStack Start guide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs/tanstack-start). | |
| For server side rendering, check out the [TanStack Start guide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs/tanstack-start). |
🤖 Prompt for AI Agents
In examples/react/18n-paraglide/README.md around line 141, there's a typo in the
SSR sentence: "rerdering" should be "rendering"; update the word to "rendering"
so the sentence reads "For server side rendering, check out the [TanStack Start
guide](https://inlang.com/m/gerre34r/library-inlang-paraglideJs/tanstack-start)."
| const { serverFunctionMessage, messageFromLoader, localeFromLoader } = | ||
| Route.useLoaderData(); |
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.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Verify proper async handling for server function.
The loader directly calls getServerMessage({ data: "📩" }) without awaiting. If this returns a Promise, it should be awaited.
Let me check the return type of server functions:
🏁 Script executed:
#!/bin/bash
# Check how server functions are used in TanStack Start examples
rg -n "createServerFn" -A 10 -B 2 --type=ts --type=tsxLength of output: 27
🏁 Script executed:
#!/bin/bash
echo "Listing src directory:"
ls -R examples/react/start-i18n-paraglide/src
echo
echo "Searching for getServerMessage definition:"
rg -n "export const getServerMessage" -C3 examples/react/start-i18n-paraglide/src
echo
echo "Searching for createServerFn usage:"
rg -n "createServerFn" -C3 examples/react/start-i18n-paraglide/srcLength of output: 1288
🏁 Script executed:
#!/bin/bash
rg -n "loader" -C5 examples/react/start-i18n-paraglide/src/routes/index.tsxLength of output: 750
Await the server function in the loader
Make the loader async and await getServerMessage so you don’t pass a Promise to the component:
loader: () => {
- return {
+ return (async () => ({
localeFromLoader: getLocale(),
messageFromLoader: m.example_message({ username: "John Doe" }),
- serverFunctionMessage: getServerMessage({ data: "📩" }),
+ serverFunctionMessage: await getServerMessage({ data: "📩" }),
}))();
},📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { serverFunctionMessage, messageFromLoader, localeFromLoader } = | |
| Route.useLoaderData(); | |
| loader: () => { | |
| return (async () => ({ | |
| localeFromLoader: getLocale(), | |
| messageFromLoader: m.example_message({ username: "John Doe" }), | |
| serverFunctionMessage: await getServerMessage({ data: "📩" }), | |
| }))(); | |
| }, |
🤖 Prompt for AI Agents
In examples/react/start-i18n-paraglide/src/routes/index.tsx around lines 24-25,
the loader currently returns a Promise for serverFunctionMessage which causes
the component to receive a Promise; update the loader function to be async and
await getServerMessage before returning so serverFunctionMessage is a resolved
value (not a Promise), and ensure the returned object uses the awaited value for
serverFunctionMessage.
| { title }, | ||
| { name: "description", content: description }, | ||
| { name: "keywords", content: keywords }, | ||
| { name: "twitter:title", content: title }, | ||
| { name: "twitter:description", content: description }, | ||
| { name: "twitter:creator", content: "@tannerlinsley" }, | ||
| { name: "twitter:site", content: "@tannerlinsley" }, | ||
| { name: "og:type", content: "website" }, | ||
| { name: "og:title", content: title }, | ||
| { name: "og:description", content: description }, | ||
| ...(image | ||
| ? [ | ||
| { name: "twitter:image", content: image }, | ||
| { name: "twitter:card", content: "summary_large_image" }, | ||
| { name: "og:image", content: image }, | ||
| ] | ||
| : []), | ||
| ]; |
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.
Avoid emitting meta tags with undefined content
description and keywords are optional, yet we still emit the matching meta descriptors with content: undefined. The downstream head manager will serialize these to content="undefined" (or at best an empty attribute), which is undesirable for SEO/preview cards and clutters the head. Please gate those descriptors on the presence of data (same for the derived Twitter/OG descriptions).
Update the block to conditionally spread only when the value exists:
- const tags = [
- { title },
- { name: "description", content: description },
- { name: "keywords", content: keywords },
- { name: "twitter:title", content: title },
- { name: "twitter:description", content: description },
- { name: "twitter:creator", content: "@tannerlinsley" },
- { name: "twitter:site", content: "@tannerlinsley" },
- { name: "og:type", content: "website" },
- { name: "og:title", content: title },
- { name: "og:description", content: description },
+ const tags = [
+ { title },
+ ...(description
+ ? [
+ { name: "description", content: description },
+ { name: "twitter:description", content: description },
+ { name: "og:description", content: description },
+ ]
+ : []),
+ ...(keywords ? [{ name: "keywords", content: keywords }] : []),
+ { name: "twitter:title", content: title },
+ { name: "twitter:creator", content: "@tannerlinsley" },
+ { name: "twitter:site", content: "@tannerlinsley" },
+ { name: "og:type", content: "website" },
+ { name: "og:title", content: title },
...(image
? [
{ name: "twitter:image", content: image },
{ name: "twitter:card", content: "summary_large_image" },
{ name: "og:image", content: image },
]
: []),
];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { title }, | |
| { name: "description", content: description }, | |
| { name: "keywords", content: keywords }, | |
| { name: "twitter:title", content: title }, | |
| { name: "twitter:description", content: description }, | |
| { name: "twitter:creator", content: "@tannerlinsley" }, | |
| { name: "twitter:site", content: "@tannerlinsley" }, | |
| { name: "og:type", content: "website" }, | |
| { name: "og:title", content: title }, | |
| { name: "og:description", content: description }, | |
| ...(image | |
| ? [ | |
| { name: "twitter:image", content: image }, | |
| { name: "twitter:card", content: "summary_large_image" }, | |
| { name: "og:image", content: image }, | |
| ] | |
| : []), | |
| ]; | |
| const tags = [ | |
| { title }, | |
| ...(description | |
| ? [ | |
| { name: "description", content: description }, | |
| { name: "twitter:description", content: description }, | |
| { name: "og:description", content: description }, | |
| ] | |
| : []), | |
| ...(keywords ? [{ name: "keywords", content: keywords }] : []), | |
| { name: "twitter:title", content: title }, | |
| { name: "twitter:creator", content: "@tannerlinsley" }, | |
| { name: "twitter:site", content: "@tannerlinsley" }, | |
| { name: "og:type", content: "website" }, | |
| { name: "og:title", content: title }, | |
| ...(image | |
| ? [ | |
| { name: "twitter:image", content: image }, | |
| { name: "twitter:card", content: "summary_large_image" }, | |
| { name: "og:image", content: image }, | |
| ] | |
| : []), | |
| ]; |
🤖 Prompt for AI Agents
In examples/react/start-i18n-paraglide/src/utils/seo.ts around lines 13 to 30,
optional fields like description, keywords, and derived twitter/og values are
currently emitted even when undefined; change the array construction to only
include meta objects when their source values exist by conditionally spreading
small arrays (e.g. ...(description ? [{ name: "description", content:
description }, { name: "twitter:description", content: description }, { name:
"og:description", content: description }] : [])) and do the same for keywords
and image so no meta tag with content: undefined is produced.
| function toUrlPattern(path: string) { | ||
| return ( | ||
| path | ||
| // catch-all | ||
| .replace(/\/\$$/, "/:path(.*)?") | ||
| // optional parameters: {-$param} | ||
| .replace(/\{-\$([a-zA-Z0-9_]+)\}/g, ":$1?") | ||
| // named parameters: $param | ||
| .replace(/\$([a-zA-Z0-9_]+)/g, ":$1") | ||
| // remove trailing slash | ||
| .replace(/\/+$/, "") | ||
| ); | ||
| } |
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.
Bug: toUrlPattern('/') returns empty string
Trailing-slash removal turns "/" into "", causing pattern "" and localized paths like "/en" vs expected "/" or "/en/". This can break matching in Vite plugin/url rewrites.
Apply:
function toUrlPattern(path: string) {
return (
path
// catch-all
.replace(/\/\$$/, "/:path(.*)?")
// optional parameters: {-$param}
.replace(/\{-\$([a-zA-Z0-9_]+)\}/g, ":$1?")
// named parameters: $param
.replace(/\$([a-zA-Z0-9_]+)/g, ":$1")
// remove trailing slash
- .replace(/\/+$/, "")
+ .replace(/\/+$/, "") || "/"
);
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| function toUrlPattern(path: string) { | |
| return ( | |
| path | |
| // catch-all | |
| .replace(/\/\$$/, "/:path(.*)?") | |
| // optional parameters: {-$param} | |
| .replace(/\{-\$([a-zA-Z0-9_]+)\}/g, ":$1?") | |
| // named parameters: $param | |
| .replace(/\$([a-zA-Z0-9_]+)/g, ":$1") | |
| // remove trailing slash | |
| .replace(/\/+$/, "") | |
| ); | |
| } | |
| function toUrlPattern(path: string) { | |
| return ( | |
| path | |
| // catch-all | |
| .replace(/\/\$$/, "/:path(.*)?") | |
| // optional parameters: {-$param} | |
| .replace(/\{-\$([a-zA-Z0-9_]+)\}/g, ":$1?") | |
| // named parameters: $param | |
| .replace(/\$([a-zA-Z0-9_]+)/g, ":$1") | |
| // remove trailing slash | |
| .replace(/\/+$/, "") || "/" | |
| ); | |
| } |
🤖 Prompt for AI Agents
In examples/react/start-i18n-paraglide/src/utils/translated-pathnames.ts around
lines 18 to 30, the trailing-slash removal can turn "/" into "" causing empty
URL patterns; update the function so after the .replace(/\/+$/, "") step you
normalize an empty result back to "/" (or if you prefer, ensure the final
returned string is "/" when the computed value is empty) so root paths remain
"/" and localized variants become "/en" or "/en/" as expected; implement this by
checking the final value and returning "/" when it's an empty string.
| return Object.entries(input).map(([pattern, locales]) => ({ | ||
| pattern: toUrlPattern(pattern), | ||
| localized: Object.entries(locales).map( | ||
| ([locale, path]) => | ||
| [locale as Locale, `/${locale}${toUrlPattern(path)}`] satisfies [ | ||
| Locale, | ||
| string, | ||
| ] | ||
| ), | ||
| })); |
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.
Ensure root localized paths don’t end with a double slash
When the base pattern is “/”, emit “/en” instead of “/en/”.
Apply:
- localized: Object.entries(locales).map(
- ([locale, path]) =>
- [locale as Locale, `/${locale}${toUrlPattern(path)}`] satisfies [
- Locale,
- string,
- ]
- ),
+ localized: Object.entries(locales).map(([locale, path]) => {
+ const p = toUrlPattern(path)
+ const suffix = p === "/" ? "" : p
+ return [locale as Locale, `/${locale}${suffix}`] as [Locale, string]
+ }),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return Object.entries(input).map(([pattern, locales]) => ({ | |
| pattern: toUrlPattern(pattern), | |
| localized: Object.entries(locales).map( | |
| ([locale, path]) => | |
| [locale as Locale, `/${locale}${toUrlPattern(path)}`] satisfies [ | |
| Locale, | |
| string, | |
| ] | |
| ), | |
| })); | |
| return Object.entries(input).map(([pattern, locales]) => ({ | |
| pattern: toUrlPattern(pattern), | |
| localized: Object.entries(locales).map(([locale, path]) => { | |
| const p = toUrlPattern(path) | |
| const suffix = p === "/" ? "" : p | |
| return [locale as Locale, `/${locale}${suffix}`] as [Locale, string] | |
| }), | |
| })); |
🤖 Prompt for AI Agents
In examples/react/start-i18n-paraglide/src/utils/translated-pathnames.ts around
lines 35–44, the code concatenates `/${locale}` with `toUrlPattern(path)` which
causes a double slash when `toUrlPattern(path)` returns '/' (root) and yields
'/en/' instead of '/en'; change the join so that when `toUrlPattern(path)` ===
'/' you append an empty string (or strip the leading slash) — e.g. compute a
suffix = toUrlPattern(path) === '/' ? '' : toUrlPattern(path) and return
`/${locale}${suffix}` to ensure root localized paths produce '/en' not '/en/'.
| "verbatimModuleSyntax": false, | ||
| "noEmit": true, |
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.
Enable verbatimModuleSyntax for ESM/bundler consistency
This example should use verbatimModuleSyntax: true (matches the other example tsconfig and avoids import elision surprises in ESM).
As a minimal fix, apply:
- "verbatimModuleSyntax": false,
+ "verbatimModuleSyntax": true,As per coding guidelines
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "verbatimModuleSyntax": false, | |
| "noEmit": true, | |
| "verbatimModuleSyntax": true, | |
| "noEmit": true, |
🤖 Prompt for AI Agents
In examples/react/start-i18n-paraglide/tsconfig.json around lines 14-15,
verbatimModuleSyntax is currently false which can cause import elision issues
for ESM; update the tsconfig to set "verbatimModuleSyntax": true (matching the
other example) so the compiler preserves import/export syntax for bundlers and
ESM, leaving "noEmit": true as-is unless other changes are required.
30a2d66 to
0babe5d
Compare
Summary by CodeRabbit
New Features
Documentation
Chores