Skip to content

Commit 1ef5039

Browse files
authored
fix: REFLEX_FRONTEND_PATH without leading slash duplicates path in logged URL (#6364)
* fixed frontend path issue * Extended test for fix * ruff formatting done * chore: ignore pyright attribute error for nt module on windows * Normalizing frontend_path fix * Added test for the fix * Fixed double path logging * fixed accidental hover link test failure
1 parent 6511f3b commit 1ef5039

4 files changed

Lines changed: 40 additions & 6 deletions

File tree

packages/reflex-base/src/reflex_base/config.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,9 @@ def _post_init(self, **kwargs):
348348
for key, env_value in env_kwargs.items():
349349
setattr(self, key, env_value)
350350

351+
# Normalize route prefixes to ensure they start with a slash.
352+
self._normalize_paths()
353+
351354
# Normalize plugins: auto-instantiate Plugin subclasses, reject bad values.
352355
self._normalize_plugins()
353356

@@ -454,6 +457,14 @@ def _normalize_disable_plugins(self):
454457
)
455458
self.disable_plugins = normalized
456459

460+
def _normalize_paths(self):
461+
"""Ensure frontend and backend paths start with a slash if provided."""
462+
if self.frontend_path and not self.frontend_path.startswith("/"):
463+
self.frontend_path = f"/{self.frontend_path}"
464+
465+
if self.backend_path and not self.backend_path.startswith("/"):
466+
self.backend_path = f"/{self.backend_path}"
467+
457468
def _add_builtin_plugins(self):
458469
"""Add the builtin plugins to the config."""
459470
for plugin in _PLUGINS_ENABLED_BY_DEFAULT:

reflex/utils/exec.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from collections.abc import Sequence
1515
from pathlib import Path
1616
from typing import Any, NamedTuple, TypedDict
17-
from urllib.parse import urljoin
1817

1918
from reflex_base import constants
2019
from reflex_base.config import get_config
@@ -270,8 +269,6 @@ def run_process_and_launch_url(
270269
if match:
271270
if first_run:
272271
url = match.group(1)
273-
if get_config().frontend_path != "":
274-
url = urljoin(url, get_config().frontend_path)
275272

276273
notify_frontend(url, backend_present)
277274
if backend_present:

tests/integration/tests_playwright/test_frontend_path.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,14 @@ def bouncer_dynamic():
214214

215215
@pytest.fixture(
216216
scope="module",
217-
params=["", "/prefix", "/prefix/nested"],
218-
ids=["no-prefix", "single-level", "two-level"],
217+
params=["", "/prefix", "/prefix/nested", "noslash", "noslash/nested"],
218+
ids=[
219+
"no-prefix",
220+
"single-level",
221+
"two-level",
222+
"noslash-single-level",
223+
"noslash-two-level",
224+
],
219225
)
220226
def frontend_path(request: pytest.FixtureRequest) -> str:
221227
"""Parametrise over no-prefix and various prefix depths.
@@ -450,3 +456,23 @@ def test_navigate_back_and_forth(frontend_path_app: AppHarness, page: Page):
450456
expect(log).to_contain_text("index")
451457
expect(log).to_contain_text("static")
452458
expect(log).to_contain_text("dynamic-7")
459+
460+
461+
def test_frontend_url_format(frontend_path_app: AppHarness, frontend_path: str):
462+
"""Verify that the frontend_url correctly incorporates the frontend_path."""
463+
url = frontend_path_app.frontend_url
464+
assert url is not None
465+
466+
from urllib.parse import urlparse
467+
468+
parsed = urlparse(url)
469+
470+
expected_path = frontend_path
471+
if expected_path and not expected_path.startswith("/"):
472+
expected_path = f"/{expected_path}"
473+
if expected_path and not expected_path.endswith("/"):
474+
expected_path = f"{expected_path}/"
475+
if not expected_path:
476+
expected_path = "/"
477+
478+
assert parsed.path == expected_path

tests/integration/tests_playwright/test_link_hover.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_link_hover(link_app: AppHarness, page: Page):
3939
assert link_app.frontend_url is not None
4040
page.goto(link_app.frontend_url)
4141

42-
link = page.get_by_role("link")
42+
link = page.get_by_role("link", name="Click me")
4343
expect(link).to_have_text("Click me")
4444
expect(link).to_have_css("color", "rgb(0, 0, 255)")
4545
link.hover()

0 commit comments

Comments
 (0)