Skip to content

ENG-9553: prepend frontend_path to RouterData.url and RouterData.page.raw_path#6535

Merged
masenf merged 2 commits into
mainfrom
masenf/router-url-frontend-path
May 20, 2026
Merged

ENG-9553: prepend frontend_path to RouterData.url and RouterData.page.raw_path#6535
masenf merged 2 commits into
mainfrom
masenf/router-url-frontend-path

Conversation

@masenf
Copy link
Copy Markdown
Collaborator

@masenf masenf commented May 20, 2026

If a frontend path is configured for the app, the framework must prepend it to the reported path, which only includes the internal route path.

…ge.raw_path

If a frontend path is configured for the app, the framework must prepend it to
the reported path, which only includes the internal route path.
@masenf masenf requested a review from a team as a code owner May 20, 2026 02:46
@linear
Copy link
Copy Markdown

linear Bot commented May 20, 2026

ENG-9553

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 20, 2026

Merging this PR will not alter performance

✅ 24 untouched benchmarks


Comparing masenf/router-url-frontend-path (e8f5945) with main (5d65aa9)

Open in CodSpeed

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 20, 2026

Greptile Summary

This PR ensures that RouterData.url and PageData.raw_path both include the configured frontend_path prefix. Previously, Next.js asPath (stored as RouteVar.ORIGIN) only carried the app-relative path, so state consumers reading router.url.path or router.page.raw_path saw a path that did not match what the browser displayed.

  • PageData.from_router_data now wraps the raw asPath with get_config().prepend_frontend_path(...) before assigning it to raw_path (and consequently full_raw_path).
  • RouterData.from_router_data applies the same transformation when building the full ReflexURL, so router.url and router.url.path reflect the browser-visible URL.
  • A new integration test (test_router_includes_frontend_path) verifies the fix across index, static, and dynamic routes for all prefix variants.

Confidence Score: 4/5

The change is safe to merge; both call sites are straightforward and the fix is well-covered by a new parameterised integration test.

The core logic is correct: Next.js strips basePath from asPath before sending it to the backend, so prepending frontend_path server-side is the right fix. The only observations are minor — get_config() is called twice per request where once would suffice, and the test has a redundant regex assertion that cannot catch anything the exact-value check misses.

No files require special attention; both changed files are straightforward.

Important Files Changed

Filename Overview
reflex/istate/data.py Prepends frontend_path to raw_path in PageData and to the URL in RouterData; get_config() is called twice per request
tests/integration/tests_playwright/test_frontend_path.py Adds _router_info() UI helper and test_router_includes_frontend_path test; contains a redundant regex assertion before an exact-value check on #router-url

Sequence Diagram

sequenceDiagram
    participant Browser
    participant Frontend as Next.js Frontend
    participant Backend as Reflex Backend
    participant RouterData as RouterData.from_router_data()

    Browser->>Frontend: Navigate to /prefix/dynamic/42
    Note over Frontend: basePath="/prefix"<br/>router.asPath="/dynamic/42"
    Frontend->>Backend: "WebSocket: {asPath: "/dynamic/42", pathname: "/dynamic/[page_id]"}"
    Backend->>RouterData: from_router_data(router_data)
    RouterData->>RouterData: "raw_path = prepend_frontend_path("/dynamic/42") -> "/prefix/dynamic/42""
    RouterData->>RouterData: "url = ReflexURL(host + "/prefix/dynamic/42")"
    RouterData-->>Backend: "RouterData(url="https://host/prefix/dynamic/42", page.raw_path="/prefix/dynamic/42")"
    Backend-->>Frontend: State delta with updated router
    Frontend-->>Browser: "router.url.path = "/prefix/dynamic/42""
Loading

Comments Outside Diff (1)

  1. reflex/istate/data.py, line 450-461 (link)

    P2 get_config() is called twice for every incoming WebSocket message: once inside PageData.from_router_data and again directly in the url= argument. Since the same config value is needed for both, fetching it once and passing it through (or at least caching the result locally) avoids the redundant lookup on every request.

Reviews (1): Last reviewed commit: "ENG-9553: prepend `frontend_path` to Rou..." | Re-trigger Greptile

Comment thread tests/integration/tests_playwright/test_frontend_path.py
adhami3310
adhami3310 previously approved these changes May 20, 2026
This is in addition to the {base} assertion which really is only a validation
that the AppHarness itself is giving us the correct link.
@masenf masenf merged commit 05b66d3 into main May 20, 2026
71 of 72 checks passed
@masenf masenf deleted the masenf/router-url-frontend-path branch May 20, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants