From e5fc5f9a831293b3f5b17f310e42fe58ac73f249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Brand=C3=A9ho?= Date: Wed, 13 Mar 2024 19:18:54 +0100 Subject: [PATCH] better default title for seo (also remove default description) (#2844) * better default title for seo (also remove default description) --- reflex/app.py | 22 ++++++++++++++++------ reflex/compiler/utils.py | 20 +++++++++++++++----- reflex/constants/route.py | 4 ++-- reflex/utils/format.py | 30 +++++++++++++++++++++++++----- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/reflex/app.py b/reflex/app.py index 2c71129c9d..081f838424 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -408,8 +408,8 @@ def add_page( self, component: Component | ComponentCallable, route: str | None = None, - title: str = constants.DefaultPage.TITLE, - description: str = constants.DefaultPage.DESCRIPTION, + title: str | None = None, + description: str | None = None, image: str = constants.DefaultPage.IMAGE, on_load: ( EventHandler | EventSpec | list[EventHandler | EventSpec] | None @@ -468,13 +468,23 @@ def add_page( component = OverlayFragment.create(component) + meta_args = { + "title": ( + title + if title is not None + else format.make_default_page_title(get_config().app_name, route) + ), + "image": image, + "meta": meta, + } + + if description is not None: + meta_args["description"] = description + # Add meta information to the component. compiler_utils.add_meta( component, - title=title, - image=image, - description=description, - meta=meta, + **meta_args, ) # Add script tags if given diff --git a/reflex/compiler/utils.py b/reflex/compiler/utils.py index 33202e56b0..9615e126b8 100644 --- a/reflex/compiler/utils.py +++ b/reflex/compiler/utils.py @@ -1,4 +1,5 @@ """Common utility functions used in the compiler.""" + from __future__ import annotations import os @@ -404,7 +405,11 @@ def get_asset_path(filename: str | None = None) -> str: def add_meta( - page: Component, title: str, image: str, description: str, meta: list[dict] + page: Component, + title: str, + image: str, + meta: list[dict], + description: str | None = None, ) -> Component: """Add metadata to a page. @@ -412,19 +417,24 @@ def add_meta( page: The component for the page. title: The title of the page. image: The image for the page. - description: The description of the page. meta: The metadata list. + description: The description of the page. Returns: The component with the metadata added. """ meta_tags = [Meta.create(**item) for item in meta] + children: list[Any] = [ + Title.create(title), + ] + if description: + children.append(Description.create(content=description)) + children.append(Image.create(content=image)) + page.children.append( Head.create( - Title.create(title), - Description.create(content=description), - Image.create(content=image), + *children, *meta_tags, ) ) diff --git a/reflex/constants/route.py b/reflex/constants/route.py index 2ed399a549..aafea9c494 100644 --- a/reflex/constants/route.py +++ b/reflex/constants/route.py @@ -50,9 +50,9 @@ class DefaultPage(SimpleNamespace): """Default page constants.""" # The default title to show for Reflex apps. - TITLE = "Reflex App" + TITLE = "{} | {}" # The default description to show for Reflex apps. - DESCRIPTION = "A Reflex app." + DESCRIPTION = "" # The default image to show for Reflex apps. IMAGE = "favicon.ico" # The default meta list to show for Reflex apps. diff --git a/reflex/utils/format.py b/reflex/utils/format.py index 0e57ca9efc..38852d7ea0 100644 --- a/reflex/utils/format.py +++ b/reflex/utils/format.py @@ -160,16 +160,17 @@ def to_camel_case(text: str, allow_hyphens: bool = False) -> str: return leading_underscores_or_hyphens + converted_word -def to_title_case(text: str) -> str: +def to_title_case(text: str, sep: str = "") -> str: """Convert a string from snake case to title case. Args: text: The string to convert. + sep: The separator to use to join the words. Returns: The title case string. """ - return "".join(word.capitalize() for word in text.split("_")) + return sep.join(word.title() for word in text.split("_")) def to_kebab_case(text: str) -> str: @@ -187,6 +188,20 @@ def to_kebab_case(text: str) -> str: return to_snake_case(text).replace("_", "-") +def make_default_page_title(app_name: str, route: str) -> str: + """Make a default page title from a route. + + Args: + app_name: The name of the app owning the page. + route: The route to make the title from. + + Returns: + The default page title. + """ + title = constants.DefaultPage.TITLE.format(app_name, route) + return to_title_case(title, " ") + + def _escape_js_string(string: str) -> str: """Escape the string for use as a JS string literal. @@ -512,9 +527,14 @@ def format_event(event_spec: EventSpec) -> str: ":".join( ( name._var_name, - wrap(json.dumps(val._var_name).strip('"').replace("`", "\\`"), "`") - if val._var_is_string - else val._var_full_name, + ( + wrap( + json.dumps(val._var_name).strip('"').replace("`", "\\`"), + "`", + ) + if val._var_is_string + else val._var_full_name + ), ) ) for name, val in event_spec.args