diff --git a/docs/app/news/+api-reference-search-titles.docs.md b/docs/app/news/+api-reference-search-titles.docs.md new file mode 100644 index 00000000000..8cb4ecc9596 --- /dev/null +++ b/docs/app/news/+api-reference-search-titles.docs.md @@ -0,0 +1 @@ +Lead API reference page titles with the public name, such as `rx.State API Reference`, so searching for `rx.State` finds its reference page. diff --git a/docs/app/reflex_docs/pages/docs/apiref.py b/docs/app/reflex_docs/pages/docs/apiref.py index e19310ccb72..0f55cb82e81 100644 --- a/docs/app/reflex_docs/pages/docs/apiref.py +++ b/docs/app/reflex_docs/pages/docs/apiref.py @@ -61,6 +61,25 @@ from .env_vars import env_vars_doc + +def _public_name(cls: type) -> str: + """Return the name users reach a class by, such as ``rx.State``. + + Search matches the identifier users type, so API reference titles lead + with it, like component titles do. + + Args: + cls: A documented class. + + Returns: + The ``rx`` or ``rx.event`` attribute path, or the bare class name. + """ + for namespace, prefix in ((rx, "rx"), (rx.event, "rx.event")): + if getattr(namespace, cls.__name__, None) is cls: + return f"{prefix}.{cls.__name__}" + return cls.__name__ + + pages = [] for module in modules: name = module.__name__.lower() @@ -72,10 +91,9 @@ f"/api-reference/{name}/", title, source_path=inspect.getsourcefile(module) )(docs) # Keep the short sidebar/nav label (e.g. "App"), but emit a descriptive HTML - # for SEO. Use the real class name (e.g. "ComponentState") so it - # reads as a proper API symbol. + # <title> that leads with the public name (e.g. "rx.State") for search. page_data.title = title - page_data.seo_title = f"{module.__name__} API Reference · Reflex Docs" + page_data.seo_title = f"{_public_name(module)} API Reference · Reflex Docs" pages.append(page_data) pages.append(env_vars_doc) diff --git a/docs/app/tests/test_routes.py b/docs/app/tests/test_routes.py index 76e5ff39d26..d26f419a617 100644 --- a/docs/app/tests/test_routes.py +++ b/docs/app/tests/test_routes.py @@ -585,3 +585,20 @@ def test_library_route_titles(routes_fixture, path, expected): """Published library pages carry the final title search engines see.""" titles = {route.path: route.seo_title or route.title for route in routes_fixture} assert titles[path] == expected + + +@pytest.mark.parametrize( + ("path", "expected"), + [ + ("/api-reference/app/", "rx.App API Reference · Reflex Docs"), + ("/api-reference/state/", "rx.State API Reference · Reflex Docs"), + ("/api-reference/var/", "rx.Var API Reference · Reflex Docs"), + ("/api-reference/eventhandler/", "rx.EventHandler API Reference · Reflex Docs"), + ("/api-reference/eventspec/", "rx.event.EventSpec API Reference · Reflex Docs"), + ("/api-reference/statemanager/", "StateManager API Reference · Reflex Docs"), + ], +) +def test_api_reference_route_titles(routes_fixture, path, expected): + """API reference titles lead with the public name users type into search.""" + titles = {route.path: route.seo_title or route.title for route in routes_fixture} + assert titles[path] == expected