From e2a836c14fb3f02ea0557e91782b806848b593bd Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 1 May 2026 10:05:40 +0200 Subject: [PATCH 1/2] use images from integration docs package instead of github --- .../pages/docs_landing/views/ai_builder.py | 8 +-- .../pages/integrations/integration_gallery.py | 8 +-- packages/reflex-site-shared/pyproject.toml | 1 + .../src/reflex_site_shared/constants.py | 1 - .../src/reflex_site_shared/gallery/common.py | 8 +-- .../src/reflex_site_shared/gallery/gallery.py | 8 +-- .../src/reflex_site_shared/integrations.py | 68 +++++++++++++++++++ uv.lock | 2 + 8 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 packages/reflex-site-shared/src/reflex_site_shared/integrations.py diff --git a/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py b/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py index 2a9fb84e9a4..f45e3c13632 100644 --- a/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py +++ b/docs/app/reflex_docs/pages/docs_landing/views/ai_builder.py @@ -4,7 +4,8 @@ import reflex as rx import reflex_components_internal as ui from reflex_site_shared.components.marquee import marquee -from reflex_site_shared.constants import INTEGRATIONS_IMAGES_URL, REFLEX_ASSETS_CDN +from reflex_site_shared.constants import REFLEX_ASSETS_CDN +from reflex_site_shared.integrations import get_integration_logo_url from reflex_docs.pages.docs import ai_builder as ai_builder_pages @@ -93,12 +94,11 @@ def card( def integration_icon_marquee(integration_name: str) -> rx.Component: - normalized_name = integration_name.lower().replace(" ", "_") return ui.avatar.root( ui.avatar.image( src=rx.color_mode_cond( - f"{INTEGRATIONS_IMAGES_URL}light/{normalized_name}.svg", - f"{INTEGRATIONS_IMAGES_URL}dark/{normalized_name}.svg", + get_integration_logo_url(integration_name, "light"), + get_integration_logo_url(integration_name, "dark"), ), unstyled=True, class_name="size-full", diff --git a/docs/app/reflex_docs/pages/integrations/integration_gallery.py b/docs/app/reflex_docs/pages/integrations/integration_gallery.py index aa5456fbf8b..6318a55c2d3 100644 --- a/docs/app/reflex_docs/pages/integrations/integration_gallery.py +++ b/docs/app/reflex_docs/pages/integrations/integration_gallery.py @@ -1,7 +1,7 @@ import reflex as rx import reflex_components_internal as ui from reflex.experimental import ClientStateVar -from reflex_site_shared.constants import INTEGRATIONS_IMAGES_URL +from reflex_site_shared.integrations import get_integration_logo_url from .integration_list import get_integration_path from .integration_request import request_integration_dialog @@ -42,15 +42,15 @@ def integration_filters(): def integration_gallery_cards(data): - integration_name = str(data["name"]).lower().replace(" ", "_") + integration_name = str(data["name"]) return rx.el.a( rx.el.div( rx.el.div( ui.avatar.root( ui.avatar.image( src=rx.color_mode_cond( - f"{INTEGRATIONS_IMAGES_URL}light/{integration_name}.svg", - f"{INTEGRATIONS_IMAGES_URL}dark/{integration_name}.svg", + get_integration_logo_url(integration_name, "light"), + get_integration_logo_url(integration_name, "dark"), ), unstyled=True, class_name="size-full", diff --git a/packages/reflex-site-shared/pyproject.toml b/packages/reflex-site-shared/pyproject.toml index 0d2f6b8865e..606a68cb37b 100644 --- a/packages/reflex-site-shared/pyproject.toml +++ b/packages/reflex-site-shared/pyproject.toml @@ -12,6 +12,7 @@ dependencies = [ "httpx", "pyyaml", "reflex-components-internal >= 0.9.0", + "reflex-integrations-docs", "reflex >= 0.9.0", "ruff-format", ] diff --git a/packages/reflex-site-shared/src/reflex_site_shared/constants.py b/packages/reflex-site-shared/src/reflex_site_shared/constants.py index 66747418c10..850ec53b1e0 100644 --- a/packages/reflex-site-shared/src/reflex_site_shared/constants.py +++ b/packages/reflex-site-shared/src/reflex_site_shared/constants.py @@ -10,7 +10,6 @@ JOBS_BOARD_URL = "https://www.ycombinator.com/companies/reflex/jobs" REFLEX_ASSETS_CDN = "https://web.reflex-assets.dev/" SCREENSHOT_BUCKET = "https://pub-c14a5dcf674640a6b73fded32bad72ca.r2.dev/" -INTEGRATIONS_IMAGES_URL = "https://raw.githubusercontent.com/reflex-dev/integrations-docs/refs/heads/main/images/logos/" REFLEX_BUILD_URL = os.getenv("REFLEX_BUILD_URL", "https://build.reflex.dev/") PIP_URL = "https://pypi.org/project/reflex" GITHUB_URL = "https://github.com/reflex-dev/reflex" diff --git a/packages/reflex-site-shared/src/reflex_site_shared/gallery/common.py b/packages/reflex-site-shared/src/reflex_site_shared/gallery/common.py index 7b7f8da3da4..202a08c4c0b 100644 --- a/packages/reflex-site-shared/src/reflex_site_shared/gallery/common.py +++ b/packages/reflex-site-shared/src/reflex_site_shared/gallery/common.py @@ -5,8 +5,9 @@ import reflex_components_internal as ui import reflex as rx -from reflex_site_shared.constants import INTEGRATIONS_IMAGES_URL, REFLEX_ASSETS_CDN +from reflex_site_shared.constants import REFLEX_ASSETS_CDN from reflex_site_shared.gallery.r_svg_loader import r_svg_loader +from reflex_site_shared.integrations import get_integration_logo_url from reflex_site_shared.utils.md import MarkdownDocument, get_md_files REFLEX_BUILD_TEMPLATES_PATH = "reflex_build_templates/" @@ -93,12 +94,11 @@ def integration_image(integration: str, class_name: str = ""): Returns: The component. """ - integration_logo = integration.replace(" ", "_").lower() return ui.avatar.root( ui.avatar.image( src=rx.color_mode_cond( - f"{INTEGRATIONS_IMAGES_URL}light/{integration_logo}.svg", - f"{INTEGRATIONS_IMAGES_URL}dark/{integration_logo}.svg", + get_integration_logo_url(integration, "light"), + get_integration_logo_url(integration, "dark"), ), unstyled=True, class_name="size-full", diff --git a/packages/reflex-site-shared/src/reflex_site_shared/gallery/gallery.py b/packages/reflex-site-shared/src/reflex_site_shared/gallery/gallery.py index ceb0da81809..36df863ea85 100644 --- a/packages/reflex-site-shared/src/reflex_site_shared/gallery/gallery.py +++ b/packages/reflex-site-shared/src/reflex_site_shared/gallery/gallery.py @@ -5,8 +5,9 @@ import reflex_components_internal as ui import reflex as rx -from reflex_site_shared.constants import INTEGRATIONS_IMAGES_URL, REFLEX_ASSETS_CDN +from reflex_site_shared.constants import REFLEX_ASSETS_CDN from reflex_site_shared.gallery.r_svg_loader import r_svg_loader +from reflex_site_shared.integrations import get_integration_logo_url from reflex_site_shared.templates.webpage import webpage from reflex_site_shared.utils.md import MarkdownDocument, get_md_files @@ -94,12 +95,11 @@ def integration_image(integration: str, class_name: str = ""): Returns: The component. """ - integration_logo = integration.replace(" ", "_").lower() return ui.avatar.root( ui.avatar.image( src=rx.color_mode_cond( - f"{INTEGRATIONS_IMAGES_URL}light/{integration_logo}.svg", - f"{INTEGRATIONS_IMAGES_URL}dark/{integration_logo}.svg", + get_integration_logo_url(integration, "light"), + get_integration_logo_url(integration, "dark"), ), unstyled=True, class_name="size-full", diff --git a/packages/reflex-site-shared/src/reflex_site_shared/integrations.py b/packages/reflex-site-shared/src/reflex_site_shared/integrations.py new file mode 100644 index 00000000000..9b073aa1ac2 --- /dev/null +++ b/packages/reflex-site-shared/src/reflex_site_shared/integrations.py @@ -0,0 +1,68 @@ +"""Helpers for resolving integration logo asset URLs from the local integrations_docs package.""" + +from pathlib import Path +from typing import Literal + +import integrations_docs +from reflex_base import constants +from reflex_base.config import get_config +from reflex_base.environment import EnvironmentVariables +from reflex_base.utils.decorator import once + + +@once +def _integrations_logos_url() -> str: + """Symlink the integrations_docs logos into assets/external and return the public URL. + + Returns: + The public frontend URL prefix for the integrations_docs logos directory. + + Raises: + RuntimeError: If the integrations_docs logos directory cannot be found. + """ + src = Path(integrations_docs.__file__).parent / "images" / "logos" + if not src.is_dir(): + msg = f"integrations_docs logos directory not found at {src}" + raise RuntimeError(msg) + relative_path = f"/{constants.Dirs.EXTERNAL_APP_ASSETS}/integrations_docs/logos/" + if not EnvironmentVariables.REFLEX_BACKEND_ONLY.get(): + dst = ( + Path.cwd() + / constants.Dirs.APP_ASSETS + / constants.Dirs.EXTERNAL_APP_ASSETS + / "integrations_docs" + / "logos" + ) + dst.parent.mkdir(parents=True, exist_ok=True) + if not dst.is_symlink() or dst.resolve() != src.resolve(): + if dst.is_symlink() or dst.exists(): + dst.unlink() + dst.symlink_to(src) + return get_config().prepend_frontend_path(relative_path) + + +def format_integration_name(integration_name: str) -> str: + """Normalize an integration name into the slug used by its logo filename. + + Args: + integration_name: The human-readable integration name. + + Returns: + The lowercase, underscore-separated slug. + """ + return integration_name.lower().replace(" ", "_") + + +def get_integration_logo_url( + integration_name: str, theme: Literal["light", "dark"] +) -> str: + """Build the public URL for an integration logo SVG. + + Args: + integration_name: The human-readable integration name. + theme: The color theme variant to load. + + Returns: + The public URL for the SVG logo. + """ + return f"{_integrations_logos_url()}{theme}/{format_integration_name(integration_name)}.svg" diff --git a/uv.lock b/uv.lock index 83b6e3daede..81f488a368e 100644 --- a/uv.lock +++ b/uv.lock @@ -3898,6 +3898,7 @@ dependencies = [ { name = "pyyaml" }, { name = "reflex" }, { name = "reflex-components-internal" }, + { name = "reflex-integrations-docs" }, { name = "ruff-format" }, ] @@ -3908,6 +3909,7 @@ requires-dist = [ { name = "pyyaml" }, { name = "reflex", editable = "." }, { name = "reflex-components-internal", editable = "packages/reflex-components-internal" }, + { name = "reflex-integrations-docs", editable = "packages/integrations-docs" }, { name = "ruff-format" }, ] From a7ca4e7aa2b0107c1b551fb2f29d34aaf2a77222 Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 1 May 2026 10:21:20 +0200 Subject: [PATCH 2/2] add this --- packages/reflex-site-shared/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/reflex-site-shared/pyproject.toml b/packages/reflex-site-shared/pyproject.toml index 606a68cb37b..0a4906e1c7c 100644 --- a/packages/reflex-site-shared/pyproject.toml +++ b/packages/reflex-site-shared/pyproject.toml @@ -49,6 +49,7 @@ dependencies = [ "reflex-components-recharts", "reflex-components-sonner", "reflex-hosting-cli", + "reflex-integrations-docs", "reflex", "ruff-format", "ruff",