Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/reflex-base/src/reflex_base/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ def _post_init(self, **kwargs):
for key, env_value in env_kwargs.items():
setattr(self, key, env_value)

# Normalize route prefixes to ensure they start with a slash.
self._normalize_paths()

# Normalize plugins: auto-instantiate Plugin subclasses, reject bad values.
self._normalize_plugins()

Expand Down Expand Up @@ -454,6 +457,14 @@ def _normalize_disable_plugins(self):
)
self.disable_plugins = normalized

def _normalize_paths(self):
"""Ensure frontend and backend paths start with a slash if provided."""
if self.frontend_path and not self.frontend_path.startswith("/"):
self.frontend_path = f"/{self.frontend_path}"

if self.backend_path and not self.backend_path.startswith("/"):
self.backend_path = f"/{self.backend_path}"

def _add_builtin_plugins(self):
"""Add the builtin plugins to the config."""
for plugin in _PLUGINS_ENABLED_BY_DEFAULT:
Expand Down
3 changes: 0 additions & 3 deletions reflex/utils/exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from collections.abc import Sequence
from pathlib import Path
from typing import Any, NamedTuple, TypedDict
from urllib.parse import urljoin

from reflex_base import constants
from reflex_base.config import get_config
Expand Down Expand Up @@ -227,8 +226,6 @@ def run_process_and_launch_url(
if match:
if first_run:
url = match.group(1)
if get_config().frontend_path != "":
url = urljoin(url, get_config().frontend_path)

notify_frontend(url, backend_present)
if backend_present:
Expand Down
30 changes: 28 additions & 2 deletions tests/integration/tests_playwright/test_frontend_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,14 @@ def bouncer_dynamic():

@pytest.fixture(
scope="module",
params=["", "/prefix", "/prefix/nested"],
ids=["no-prefix", "single-level", "two-level"],
params=["", "/prefix", "/prefix/nested", "noslash", "noslash/nested"],
ids=[
"no-prefix",
"single-level",
"two-level",
"noslash-single-level",
"noslash-two-level",
],
)
def frontend_path(request: pytest.FixtureRequest) -> str:
"""Parametrise over no-prefix and various prefix depths.
Expand Down Expand Up @@ -450,3 +456,23 @@ def test_navigate_back_and_forth(frontend_path_app: AppHarness, page: Page):
expect(log).to_contain_text("index")
expect(log).to_contain_text("static")
expect(log).to_contain_text("dynamic-7")


def test_frontend_url_format(frontend_path_app: AppHarness, frontend_path: str):
"""Verify that the frontend_url correctly incorporates the frontend_path."""
url = frontend_path_app.frontend_url
assert url is not None

from urllib.parse import urlparse

parsed = urlparse(url)

expected_path = frontend_path
if expected_path and not expected_path.startswith("/"):
expected_path = f"/{expected_path}"
if expected_path and not expected_path.endswith("/"):
expected_path = f"{expected_path}/"
if not expected_path:
expected_path = "/"

assert parsed.path == expected_path
2 changes: 1 addition & 1 deletion tests/integration/tests_playwright/test_link_hover.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_link_hover(link_app: AppHarness, page: Page):
assert link_app.frontend_url is not None
page.goto(link_app.frontend_url)

link = page.get_by_role("link")
link = page.get_by_role("link", name="Click me")
expect(link).to_have_text("Click me")
expect(link).to_have_css("color", "rgb(0, 0, 255)")
link.hover()
Expand Down
Loading