diff --git a/reflex/route.py b/reflex/route.py index 0986f7138..3f50eb96e 100644 --- a/reflex/route.py +++ b/reflex/route.py @@ -19,6 +19,10 @@ def verify_route_validity(route: str) -> None: pattern = catchall_in_route(route) if pattern and not route.endswith(pattern): raise ValueError(f"Catch-all must be the last part of the URL: {route}") + if route == "api" or route.startswith("api/"): + raise ValueError( + f"Cannot have a route prefixed with 'api/': {route} (conflicts with NextJS)" + ) def get_route_args(route: str) -> dict[str, str]: diff --git a/tests/test_app.py b/tests/test_app.py index de7e5cdd9..b3153078a 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -275,6 +275,28 @@ def test_add_page_set_route_nested(app: App, index_page, windows_platform: bool) assert set(app.pages.keys()) == {route.strip(os.path.sep)} +def test_add_page_invalid_api_route(app: App, index_page): + """Test adding a page with an invalid route to an app. + + Args: + app: The app to test. + index_page: The index page. + """ + with pytest.raises(ValueError): + app.add_page(index_page, route="api") + with pytest.raises(ValueError): + app.add_page(index_page, route="/api") + with pytest.raises(ValueError): + app.add_page(index_page, route="/api/") + with pytest.raises(ValueError): + app.add_page(index_page, route="api/foo") + with pytest.raises(ValueError): + app.add_page(index_page, route="/api/foo") + # These should be fine + app.add_page(index_page, route="api2") + app.add_page(index_page, route="/foo/api") + + def test_initialize_with_admin_dashboard(test_model): """Test setting the admin dashboard of an app.