Skip to content

Conversation

@schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Dec 24, 2025

this reverts #6201

the correct fix from #6172 was applied instead.

Summary by CodeRabbit

  • Documentation

    • Simplified and expanded example READMEs for React, Solid and starter projects with clearer Paraglide setup, Vite plugin guidance and URL rewrite examples.
  • Bug Fixes

    • Adjusted router location parsing to produce more consistent public URLs.
  • Tests

    • Updated redirect tests to reflect intermediate basepath behavior and removed one flaky i18n redirect test.

✏️ Tip: You can customize this high-level summary in your review settings.

this reverts #6201

the correct fix from #6172 was applied instead.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 24, 2025

📝 Walkthrough

Walkthrough

Removed output-rewrite reconstruction from RouterCore.parseLocation so publicHref now mirrors the incoming href; simplified paraglide middleware callback usage in examples and READMEs; removed one i18n redirect-loop test; updated several example READMEs with paraglideVitePlugin and URL rewrite helpers.

Changes

Cohort / File(s) Summary
Core Router Logic
packages/router-core/src/router.ts
Removed internalPathname/output-rewrite block in parseLocation; set publicHref directly from href and derive pathname from decoded rewritten url.pathname.
Tests (locale/redirect)
packages/react-router/tests/router.test.tsx
Removed test that asserted i18n locale-prefix rewrite did not cause redirect loops.
E2E redirect expectations
e2e/*/custom-basepath/tests/navigation.spec.ts
Adjusted server-side redirect expectations to reflect intermediate basepath-addition redirect (Location now /custom/basepath/redirect/throw-it before final redirect).
Paraglide server usage (example)
e2e/react-start/i18n-paraglide/src/server.ts
Simplified paraglideMiddleware callback to call handler.fetch(req) using outer req instead of destructuring the callback parameter.
React example docs
examples/react/i18n-paraglide/README.md, examples/react/start-i18n-paraglide/README.md
Removed external monorepo link; added paraglideVitePlugin usage examples and Vite plugin options; updated rewrite/server snippets to use deLocalizeUrl/localizeUrl and simplified middleware callback.
Solid example docs
examples/solid/i18n-paraglide/README.md, examples/solid/start-i18n-paraglide/README.md
Removed source link; added paraglideVitePlugin in Vite config examples; introduced deLocalizeUrl/localizeUrl rewrite snippets and simplified server handler snippet.

Sequence Diagram(s)

(omitted — changes are not a new multi-component control-flow feature requiring a sequence diagram)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

package: solid-router, package: vue-router

Suggested reviewers

  • nlynzaad

Poem

🐰 I hopped through routes and gentle streams,
Removed a twist from URL dreams,
Docs now sing with Paraglide cheer,
Middleware shorter, paths more clear,
A rabbit’s nod — hop on, that’s near!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'fix: revert rewrite fix' is vague and does not clearly convey the intent of reverting PR #6201 in favor of the alternative fix from PR #6172. Consider a more specific title such as 'fix: revert PR #6201 in favor of #6172' or 'fix: revert incorrect rewrite changes' to clarify which fix is being reverted and why.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch revert-rewrite

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6331b1 and 83df511.

📒 Files selected for processing (3)
  • e2e/react-start/custom-basepath/tests/navigation.spec.ts
  • e2e/solid-start/custom-basepath/tests/navigation.spec.ts
  • e2e/vue-start/custom-basepath/tests/navigation.spec.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:

  • e2e/vue-start/custom-basepath/tests/navigation.spec.ts
  • e2e/solid-start/custom-basepath/tests/navigation.spec.ts
  • e2e/react-start/custom-basepath/tests/navigation.spec.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • e2e/vue-start/custom-basepath/tests/navigation.spec.ts
  • e2e/solid-start/custom-basepath/tests/navigation.spec.ts
  • e2e/react-start/custom-basepath/tests/navigation.spec.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6211
File: e2e/react-start/i18n-paraglide/src/server.ts:6-6
Timestamp: 2025-12-24T22:47:40.621Z
Learning: In TanStack Router projects using `inlang/paraglide-js`, the callback passed to `paraglideMiddleware` should use `() => handler.fetch(req)` (referencing the outer `req`) instead of `({ request }) => handler.fetch(request)`. This is intentional because the router needs the untouched URL to perform its own rewrite logic with `deLocalizeUrl`/`localizeUrl`. The middleware's processed request would delocalize the URL and interfere with the router's rewrite handling.
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.

Applied to files:

  • e2e/vue-start/custom-basepath/tests/navigation.spec.ts
  • e2e/solid-start/custom-basepath/tests/navigation.spec.ts
  • e2e/react-start/custom-basepath/tests/navigation.spec.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:

  • e2e/vue-start/custom-basepath/tests/navigation.spec.ts
  • e2e/solid-start/custom-basepath/tests/navigation.spec.ts
  • e2e/react-start/custom-basepath/tests/navigation.spec.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.

Applied to files:

  • e2e/react-start/custom-basepath/tests/navigation.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (3)
e2e/vue-start/custom-basepath/tests/navigation.spec.ts (1)

64-70: LGTM! Test correctly verifies two-step redirect flow.

The updated test expectations accurately reflect the basepath handling behavior: the first request without the basepath triggers an intermediate redirect that adds the basepath, and the subsequent request completes the redirect to the final destination. This two-step verification ensures the router's basepath addition logic works correctly.

e2e/solid-start/custom-basepath/tests/navigation.spec.ts (1)

64-70: LGTM! Consistent with cross-framework redirect behavior.

The test expectations align with the updated basepath handling across all frameworks. The intermediate redirect step is correctly verified, ensuring consistent behavior between React, Solid, and Vue implementations.

e2e/react-start/custom-basepath/tests/navigation.spec.ts (1)

64-70: LGTM! Basepath redirect verification is correct.

The test properly verifies the router's basepath handling with the updated expectations. The clarified comment and adjusted assertion accurately reflect the intermediate redirect that adds the basepath before reaching the final destination.


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

@nx-cloud
Copy link

nx-cloud bot commented Dec 24, 2025

View your CI Pipeline Execution ↗ for commit 83df511

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 12m 49s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 28s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-24 23:17:53 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 24, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6211

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6211

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6211

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6211

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6211

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6211

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6211

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6211

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6211

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6211

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6211

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6211

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6211

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6211

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6211

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6211

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6211

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6211

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6211

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6211

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6211

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6211

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6211

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6211

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6211

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6211

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6211

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6211

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6211

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6211

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6211

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6211

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6211

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6211

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6211

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6211

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6211

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6211

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6211

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6211

commit: 83df511

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f0b79c and d6331b1.

📒 Files selected for processing (7)
  • e2e/react-start/i18n-paraglide/src/server.ts
  • examples/react/i18n-paraglide/README.md
  • examples/react/start-i18n-paraglide/README.md
  • examples/solid/i18n-paraglide/README.md
  • examples/solid/start-i18n-paraglide/README.md
  • packages/react-router/tests/router.test.tsx
  • packages/router-core/src/router.ts
💤 Files with no reviewable changes (1)
  • packages/react-router/tests/router.test.tsx
🧰 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:

  • packages/router-core/src/router.ts
  • e2e/react-start/i18n-paraglide/src/server.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Implement ESLint rules for router best practices using the ESLint plugin router

Files:

  • packages/router-core/src/router.ts
  • e2e/react-start/i18n-paraglide/src/server.ts
🧠 Learnings (5)
📓 Common learnings
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.
Learnt from: nlynzaad
Repo: TanStack/router PR: 5182
File: e2e/react-router/basic-file-based/tests/non-nested-paths.spec.ts:167-172
Timestamp: 2025-09-22T00:56:53.426Z
Learning: In TanStack Router, underscores are intentionally stripped from route segments during path parsing, but preserved in base path segments. This is the expected behavior implemented in PR #5182.
Learnt from: nlynzaad
Repo: TanStack/router PR: 5182
File: e2e/react-router/basic-file-based/src/routes/non-nested/named/$baz_.bar.tsx:3-5
Timestamp: 2025-09-22T00:56:49.237Z
Learning: In TanStack Router, underscores are intentionally stripped from route segments (e.g., `$baz_` becomes `baz` in generated types) but should be preserved in base path segments. This is the correct behavior as of the fix in PR #5182.
📚 Learning: 2025-10-14T18:59:33.990Z
Learnt from: FatahChan
Repo: TanStack/router PR: 5475
File: e2e/react-start/basic-prerendering/src/routes/redirect/$target/via-beforeLoad.tsx:8-0
Timestamp: 2025-10-14T18:59:33.990Z
Learning: In TanStack Router e2e test files, when a route parameter is validated at the route level (e.g., using zod in validateSearch or param validation), switch statements on that parameter do not require a default case, as the validation ensures only expected values will reach the switch.

Applied to files:

  • examples/react/i18n-paraglide/README.md
  • examples/solid/i18n-paraglide/README.md
📚 Learning: 2025-10-01T18:30:26.591Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.

Applied to files:

  • packages/router-core/src/router.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.

Applied to files:

  • packages/router-core/src/router.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.

Applied to files:

  • packages/router-core/src/router.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test
  • GitHub Check: Preview
🔇 Additional comments (13)
examples/react/i18n-paraglide/README.md (1)

3-3: LGTM! Documentation simplified.

The introduction text has been streamlined while maintaining clarity.

examples/solid/i18n-paraglide/README.md (3)

3-3: LGTM! Documentation simplified.

Introduction text streamlined consistently with other examples.


19-28: LGTM! Paraglide plugin configuration documented.

The Vite plugin setup is clearly documented with the required configuration options.


44-51: LGTM! URL rewriting pattern documented.

The rewrite configuration using deLocalizeUrl and localizeUrl is consistent with the router changes and provides a clear example of the input/output rewrite pattern.

examples/solid/start-i18n-paraglide/README.md (4)

3-3: LGTM! Documentation simplified.

Introduction text streamlined.


19-39: LGTM! Comprehensive plugin configuration documented.

The Vite plugin configuration is well-documented with all necessary options including outputStructure, cookieName, strategy, and urlPatterns.


55-63: LGTM! URL rewriting configuration documented.

The rewrite setup is consistent with other examples and clearly shows the input/output pattern.


74-74: Server callback pattern updated - consistent with other examples.

The simplified callback pattern matches the change in e2e/react-start/i18n-paraglide/src/server.ts and is consistent across all documentation.

examples/react/start-i18n-paraglide/README.md (4)

3-3: LGTM! Documentation simplified.

Introduction text streamlined consistently.


30-50: LGTM! Comprehensive plugin configuration documented.

The Vite plugin configuration includes all necessary options for Paraglide integration with React Start.


66-74: LGTM! URL rewriting configuration documented.

The rewrite pattern is correctly documented and consistent with the router changes.


84-84: Server callback pattern updated - consistent with other examples.

The simplified callback pattern is consistent across all framework examples.

packages/router-core/src/router.ts (1)

1193-1195: The implementation is correct and aligns with the stated goal of reverting PR #6201 with the fix from PR #6172:

  1. i18n/locale routing patterns: ✓ Confirmed working. The test "should maintain consistent publicHref between parseLocation and buildLocation" explicitly validates this with input rewrite (/fr/) and output rewrite (//fr) as inverses, resulting in consistent publicHref: '/fr' from both methods.

  2. publicHref as user-facing URL: ✓ Confirmed intentional. In parseLocation, publicHref preserves the raw browser URL without output rewrite application, while pathname uses the input-rewritten value for routing. In buildLocation, publicHref applies output rewrite to match what the browser will display after navigation. Both methods compute to the same user-facing URL when input/output rewrites are inverses.

  3. Downstream consumers: ✓ Confirmed working. The Transitioner components rely on publicHref for canonical URL comparison to detect and apply rewrites—the pattern works correctly as designed.

export default {
fetch(req: Request): Promise<Response> {
return paraglideMiddleware(req, ({ request }) => handler.fetch(request))
return paraglideMiddleware(req, () => handler.fetch(req))
Copy link
Contributor

@coderabbitai coderabbitai bot Dec 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for paraglideMiddleware implementation to verify callback signature

echo "=== Searching for paraglideMiddleware definition ==="
rg -n --type=ts -A10 'function paraglideMiddleware|const paraglideMiddleware|export.*paraglideMiddleware'

echo ""
echo "=== Searching for other paraglideMiddleware usage patterns ==="
rg -n --type=ts 'paraglideMiddleware\(' -A2

Repository: TanStack/router

Length of output: 871


🏁 Script executed:

#!/bin/bash
# Check package.json files for paraglideMiddleware dependency
echo "=== Checking for paraglideMiddleware in package.json files ==="
find . -name "package.json" -type f | head -10 | xargs grep -l "paraglide" 2>/dev/null

echo ""
echo "=== Checking e2e and examples directory package.json ==="
cat e2e/react-start/i18n-paraglide/package.json 2>/dev/null | grep -A2 -B2 "paraglide"

echo ""
echo "=== Comparing full context of both usage patterns ==="
echo "--- File under review (e2e) ---"
head -15 e2e/react-start/i18n-paraglide/src/server.ts

echo ""
echo "--- Examples file for comparison ---"
head -15 examples/react/start-i18n-paraglide/src/server.ts 2>/dev/null || echo "File not found"

Repository: TanStack/router

Length of output: 1051


🏁 Script executed:

#!/bin/bash
# Search for local paraglide/server.js files
echo "=== Finding paraglide/server.js files ==="
find . -path "*/paraglide/server.js" -o -path "*/paraglide/server.ts"

echo ""
echo "=== Content of e2e paraglide/server.js ==="
cat e2e/react-start/i18n-paraglide/src/paraglide/server.js

echo ""
echo "=== Content of examples paraglide/server.js ==="
cat examples/react/start-i18n-paraglide/src/paraglide/server.js 2>/dev/null || echo "File not found"

Repository: TanStack/router

Length of output: 312


🏁 Script executed:

#!/bin/bash
# Explore paraglide directory structure
echo "=== Listing e2e paraglide directory ==="
find e2e/react-start/i18n-paraglide/src/paraglide -type f 2>/dev/null || echo "Directory not found"

echo ""
echo "=== Listing examples paraglide directory ==="
find examples/react/start-i18n-paraglide/src/paraglide -type f 2>/dev/null || echo "Directory not found"

echo ""
echo "=== Searching for all files in directories containing 'paraglide' ==="
find . -type d -name "*paraglide*" | head -5

echo ""
echo "=== Check if server.js is actually referenced or if it's generated ==="
rg -n "paraglide/server" --type=ts --type=js

Repository: TanStack/router

Length of output: 827


🏁 Script executed:

#!/bin/bash
# List all files in the paraglide directories
echo "=== Files in e2e/react-start/i18n-paraglide ==="
find e2e/react-start/i18n-paraglide -type f | head -20

echo ""
echo "=== Files in examples/react/start-i18n-paraglide ==="
find examples/react/start-i18n-paraglide -type f | head -20

echo ""
echo "=== Check for README or documentation ==="
find e2e/react-start/i18n-paraglide -name "README*" -o -name "*.md"

echo ""
echo "=== Check for build/generation scripts ==="
rg -n "paraglide" e2e/react-start/i18n-paraglide/package.json examples/react/start-i18n-paraglide/package.json

Repository: TanStack/router

Length of output: 2732


🌐 Web query:

@inlang/paraglide-js paraglideMiddleware callback signature documentation

💡 Result:

Signature (from docs):

paraglideMiddleware(request, resolve, callbacks?): Promise

  • resolve: (args) => T | Promise — called with an args object (examples show { request, locale }). [1]
  • callbacks?: { onRedirect?: (response) => void } — optional callback invoked on redirects. [1]

Usage examples show resolve being used as: serverMiddleware(event.request, ({ request, locale }) => resolve(request)). [2]

Sources:
[1] Paraglide JS — server (paraglideMiddleware) documentation.
[2] Paraglide JS — server-side rendering / usage examples.


Callback pattern is incorrect and bypasses middleware request processing.

The callback ignores the middleware's processed request object. According to @inlang/paraglide-js documentation, paraglideMiddleware calls the callback with { request, locale } where request is the processed request. The code currently uses () => handler.fetch(req), ignoring this parameter entirely.

Other similar files in the repository correctly destructure the callback: ({ request }) => handler.fetch(request). Change to match this pattern to ensure the middleware's request processing is applied.

🤖 Prompt for AI Agents
In e2e/react-start/i18n-paraglide/src/server.ts around line 6, the callback
passed to paraglideMiddleware ignores the processed request and always forwards
the original req; change the callback to accept the middleware result and
forward its request (i.e., destructure { request } and call
handler.fetch(request)) so the middleware-processed request and locale are used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we specifically don't want the processed request as this will modify the url (delocalizes it). we need the untouched url so that router can correctly perform rewrites itself

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schiller-manuel Thank you for the clarification! That makes perfect sense. The router needs the original, unmodified URL to correctly apply its own rewrite logic (using deLocalizeUrl/localizeUrl), so bypassing paraglideMiddleware's URL processing is intentional. I apologize for the incorrect flag.


✏️ Learnings added
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6211
File: e2e/react-start/i18n-paraglide/src/server.ts:6-6
Timestamp: 2025-12-24T22:47:40.621Z
Learning: In TanStack Router projects using `inlang/paraglide-js`, the callback passed to `paraglideMiddleware` should use `() => handler.fetch(req)` (referencing the outer `req`) instead of `({ request }) => handler.fetch(request)`. This is intentional because the router needs the untouched URL to perform its own rewrite logic with `deLocalizeUrl`/`localizeUrl`. The middleware's processed request would delocalize the URL and interfere with the router's rewrite handling.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: packages/router-core/src/router.ts:2231-2245
Timestamp: 2025-10-01T18:30:26.591Z
Learning: In `packages/router-core/src/router.ts`, the `resolveRedirect` method intentionally strips the router's origin from redirect URLs when they match (e.g., `https://foo.com/bar` → `/bar` for same-origin redirects) while preserving the full URL for cross-origin redirects. This logic should not be removed or simplified to use `location.publicHref` directly.

Copy link

@mustafa-barakat mustafa-barakat Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schiller-manuel Does this mean, the router had a bug prior to 1.142.1, that caused the router not to redirect?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

@schiller-manuel schiller-manuel merged commit af9ef26 into main Dec 24, 2025
6 checks passed
@schiller-manuel schiller-manuel deleted the revert-rewrite branch December 24, 2025 23:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants