Skip to content

Conversation

schiller-manuel
Copy link
Contributor

@schiller-manuel schiller-manuel commented Sep 30, 2025

fixes #5300

Summary by CodeRabbit

  • Bug Fixes
    • Corrected localhost examples to use http, avoiding TLS/mixed-content issues.
    • Improved SSR origin detection for more reliable URL construction.
    • Redirects now normalize to relative paths, preventing incorrect absolute-origin links.
  • Refactor
    • Centralized origin resolution and exported a shared origin utility for consistent server and router behavior.

Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Centralizes server-side origin resolution with a new getOrigin(request) utility, uses it across SSR/start handlers, normalizes redirect hrefs by stripping matching origins to paths, and updates example apps to use http://localhost:3000 (protocol change only).

Changes

Cohort / File(s) Summary
Examples: localhost protocol tweak
examples/react/basic-ssr-file-based/src/entry-server.tsx, examples/react/basic-ssr-streaming-file-based/src/entry-server.tsx
Switch base URL from https://localhost:3000 to http://localhost:3000 when constructing fetch-equivalent request URLs. No other logic changes.
SSR origin utility: addition and re-exports
packages/router-core/src/ssr/ssr-server.ts, packages/router-core/src/ssr/server.ts
Add and export getOrigin(request) which derives origin from the Origin header or request.url, with fallback to http://localhost; re-export getOrigin from the public SSR server module.
SSR request/start handlers: unified origin usage
packages/router-core/src/ssr/createRequestHandler.ts, packages/start-server-core/src/createStartHandler.ts
Import and use getOrigin(request) to compute origin for fetch patching and router update; set router origin to router.options.origin ?? origin; remove duplicated local origin logic.
Redirect normalization
packages/router-core/src/router.ts
In resolveRedirect, when href is absent, build the URL via the location builder and, if it starts with the router origin, strip that origin to produce a path (defaulting to /); set redirect.options.href and the Location header accordingly.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Server
  participant SSRHandler as SSR Handler
  participant Router
  participant Util as getOrigin

  Client->>Server: HTTP request
  Server->>SSRHandler: handle(request)
  SSRHandler->>Util: getOrigin(request)
  Util-->>SSRHandler: origin
  SSRHandler->>Router: update({ origin: router.options.origin ?? origin })
  alt route triggers redirect
    Router->>Router: resolveRedirect() (build URL via location builder)
    Router->>Router: strip origin if matching -> path (fallback '/')
    Router-->>SSRHandler: redirect with href/path and Location header
    SSRHandler-->>Server: 3xx response
    Server-->>Client: Redirect
  else render
    SSRHandler-->>Server: SSR response (200)
    Server-->>Client: HTML/stream
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • chorobin

Poem

I sniff the headers, hop with glee,
Find origins clear as they can be.
I strip the host and trim the start,
Turn absolute paths into art.
Streams hum softly, redirects sing —
I thump my foot: "Deploy the spring!" 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The addition of a debug log in the streaming SSR example and the protocol change from https to http in the example entry‐server files do not relate to fixing the redirect‐rewrite issue and introduce functionality outside the scope of issue #5300. Please remove the debug logging from the example code and isolate or justify the protocol change in a separate commit so that the PR only contains changes directly necessary to restore rewrite‐aware redirects.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “fix: redirect respects rewrites” succinctly describes the primary change—ensuring redirects preserve the configured rewrite base path—and uses conventional commit style. It clearly conveys the main intent without extraneous details, making it easy for reviewers to understand the core fix at a glance.
Linked Issues Check ✅ Passed The pull request implements the requested behavior from issue #5300 by computing the correct origin via a new getOrigin utility and updating the SSR request handler to use that origin when generating redirect URLs, and by stripping the origin only after the full URL (including rewrite base path) is constructed. This change ensures that server‐side redirects thrown in beforeLoad now include the application’s base path as expected.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6e1e48 and 86a5961.

📒 Files selected for processing (3)
  • examples/react/basic-ssr-streaming-file-based/src/entry-server.tsx (1 hunks)
  • packages/router-core/src/router.ts (1 hunks)
  • packages/start-server-core/src/createStartHandler.ts (5 hunks)

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

Copy link

nx-cloud bot commented Sep 30, 2025

View your CI Pipeline Execution ↗ for commit 86a5961

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

☁️ Nx Cloud last updated this comment at 2025-09-30 18:43:26 UTC

Copy link

pkg-pr-new bot commented Sep 30, 2025

More templates

@tanstack/arktype-adapter

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

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5315

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5315

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/zod-adapter

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

commit: c6e1e48

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: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 581941a and c6e1e48.

📒 Files selected for processing (7)
  • examples/react/basic-ssr-file-based/src/entry-server.tsx (1 hunks)
  • examples/react/basic-ssr-streaming-file-based/src/entry-server.tsx (2 hunks)
  • packages/router-core/src/router.ts (1 hunks)
  • packages/router-core/src/ssr/createRequestHandler.ts (3 hunks)
  • packages/router-core/src/ssr/server.ts (1 hunks)
  • packages/router-core/src/ssr/ssr-server.ts (1 hunks)
  • packages/start-server-core/src/createStartHandler.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript in strict mode with extensive type safety across the codebase

Files:

  • examples/react/basic-ssr-file-based/src/entry-server.tsx
  • packages/router-core/src/ssr/ssr-server.ts
  • packages/router-core/src/ssr/server.ts
  • packages/router-core/src/router.ts
  • packages/start-server-core/src/createStartHandler.ts
  • packages/router-core/src/ssr/createRequestHandler.ts
  • examples/react/basic-ssr-streaming-file-based/src/entry-server.tsx
examples/{react,solid}/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep example applications under examples/react/ and examples/solid/

Files:

  • examples/react/basic-ssr-file-based/src/entry-server.tsx
  • examples/react/basic-ssr-streaming-file-based/src/entry-server.tsx
packages/router-core/**

📄 CodeRabbit inference engine (AGENTS.md)

Keep framework-agnostic core router logic in packages/router-core/

Files:

  • packages/router-core/src/ssr/ssr-server.ts
  • packages/router-core/src/ssr/server.ts
  • packages/router-core/src/router.ts
  • packages/router-core/src/ssr/createRequestHandler.ts
packages/{*-start,start-*}/**

📄 CodeRabbit inference engine (AGENTS.md)

Name and place Start framework packages under packages/-start/ or packages/start-/

Files:

  • packages/start-server-core/src/createStartHandler.ts
🧬 Code graph analysis (4)
packages/router-core/src/ssr/ssr-server.ts (1)
packages/router-core/src/ssr/server.ts (1)
  • getOrigin (10-10)
packages/router-core/src/router.ts (1)
packages/router-core/src/redirect.ts (1)
  • redirect (57-93)
packages/start-server-core/src/createStartHandler.ts (1)
packages/router-core/src/ssr/ssr-server.ts (1)
  • getOrigin (145-157)
packages/router-core/src/ssr/createRequestHandler.ts (1)
packages/router-core/src/ssr/ssr-server.ts (1)
  • getOrigin (145-157)
⏰ 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: Preview
  • GitHub Check: Test
🔇 Additional comments (10)
examples/react/basic-ssr-streaming-file-based/src/entry-server.tsx (1)

21-21: Protocol change looks intentional but verify consistency.

The base URL protocol changed from https to http. This aligns with the new getOrigin utility's fallback default of 'http://localhost' (as seen in the related changes). Ensure this matches your local development environment configuration.

examples/react/basic-ssr-file-based/src/entry-server.tsx (1)

21-21: LGTM! Consistent protocol change.

The base URL protocol change from https to http is consistent with the streaming variant and aligns with the centralized origin resolution strategy introduced in this PR.

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

10-10: LGTM! Exports new origin resolution utility.

The addition of getOrigin to the public exports enables consumers to use the centralized origin resolution logic. This is part of the broader refactoring to standardize origin handling across SSR flows.

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

3-3: LGTM! Centralized origin resolution for SSR.

The changes properly:

  1. Import the new getOrigin utility
  2. Compute the origin from the request using getOrigin(request)
  3. Respect explicit router.options.origin configuration while falling back to the computed origin

This ensures consistent origin handling across SSR flows and integrates cleanly with the redirect resolution fix.

Also applies to: 30-42

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

2231-2246: Ensure path-only hrefs are supported by router.navigate in all contexts.
Test the redirect flow in both SSR (start-server, router-ssr-query) and CSR (solid-start, react-start, load-matches) to confirm router.navigate(resolveRedirect(err).options) correctly handles relative options.href. Validate reproduction of issue #5300: navigating from /my-app/posts/2 should redirect to /my-app/error rather than /error.

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

145-157: LGTM! Clean origin resolution with sensible fallbacks.

The implementation correctly prioritizes the Origin header, falls back to parsing request.url, and provides a safe default. The try/catch blocks appropriately handle invalid URLs without exposing error details.

packages/start-server-core/src/createStartHandler.ts (4)

14-17: Good refactor: centralizing origin resolution.

Moving to a shared getOrigin utility from @tanstack/router-core/ssr/server improves consistency across SSR handlers.


100-100: LGTM! Consistent origin computation.

Computing the origin once at the start of the request handler ensures consistent origin resolution across fetch patching and router initialization.


115-115: LGTM! Fetch patching uses consistent origin.

Both URL construction paths (string input and Request object) correctly use the shared origin value, ensuring relative URLs resolve consistently.

Also applies to: 124-124


161-161: LGTM! Correct origin precedence for redirect resolution.

The fallback logic router.options.origin ?? origin correctly prioritizes explicit configuration while using the computed origin from the request when not specified. This should ensure redirects respect the rewrite base path as intended in the PR objectives.

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.

throw redirect in beforeLoad with rewriteBasePath ignores the rewrite

1 participant