Skip to content

feat(theming): add per-theme custom font URL support#36317

Merged
rusackas merged 3 commits intoapache:masterfrom
gabotorresruiz:feat/add-custom-fonts-support
Dec 9, 2025
Merged

feat(theming): add per-theme custom font URL support#36317
rusackas merged 3 commits intoapache:masterfrom
gabotorresruiz:feat/add-custom-fonts-support

Conversation

@gabotorresruiz
Copy link
Copy Markdown
Contributor

SUMMARY

Adds support for custom font URLs in theme configurations and migrates default fonts from bundled packages to CDN loading. Now we can specify a fontUrls array in theme tokens to load external fonts (Google Fonts, Adobe Fonts) that are automatically injected when the theme is applied.

  • Removes bundled @fontsource packages in favor of loading Inter and Fira Code via Google Fonts
  • Removes CUSTOM_FONT_URLS config in favor of per-theme fontUrls in theme tokens
  • Configures CSP to dynamically allow font domains from THEME_FONT_URL_ALLOWED_DOMAINS

AFTER SCREENSHOTS OR ANIMATED GIF

theme-custom-fonts

TESTING INSTRUCTIONS

  1. Create/update a theme with fontFamily and fontUrls in the token configuration:
{
  "token": {
    "fontFamily": "Science Gothic, sans-serif",
    "fontUrls": ["https://fonts.googleapis.com/css2?family=Science+Gothic:wght@100..900&display=swap"]
  },
  "algorithm": "dark"
}
  1. Apply the theme and verify the font loads correctly

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

@dosubot dosubot Bot added the global:theming Related to theming Superset label Nov 28, 2025
Copy link
Copy Markdown
Contributor

@bito-code-review bito-code-review Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Agent Run #607d71

Actionable Suggestions - 2
  • superset-frontend/src/theme/ThemeController.ts - 1
  • superset-frontend/src/theme/tests/ThemeController.test.ts - 1
Additional Suggestions - 1
  • superset/themes/schemas.py - 1
    • Code duplication in validation logic · Line 52-56
      The font URL validation code added here is duplicated in two other methods in this file (lines 92-96 and 129-133). Consider extracting this logic into a shared helper method to avoid potential inconsistencies if one copy is updated without the others.
Review Details
  • Files reviewed - 9 · Commit Range: aa89c0e..b729d17
    • superset-frontend/packages/superset-core/src/ui/theme/GlobalStyles.tsx
    • superset-frontend/packages/superset-core/src/ui/theme/types.ts
    • superset-frontend/src/theme/ThemeController.ts
    • superset-frontend/src/theme/tests/ThemeController.test.ts
    • superset/config.py
    • superset/templates/superset/spa.html
    • superset/themes/schemas.py
    • superset/themes/utils.py
    • tests/unit_tests/themes/test_utils.py
  • Files skipped - 2
    • superset-frontend/packages/superset-core/package.json - Reason: Filter setting
    • superset-frontend/packages/superset-ui-core/package.json - Reason: Filter setting
  • Tools
    • Eslint (Linter) - ✔︎ Successful
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Default Agent You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment thread superset-frontend/src/theme/ThemeController.ts
Comment thread superset-frontend/src/theme/tests/ThemeController.test.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented Nov 28, 2025

Codecov Report

❌ Patch coverage is 35.55556% with 29 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.96%. Comparing base (fd7ce49) to head (bc2ed74).
⚠️ Report is 65 commits behind head on master.

Files with missing lines Patch % Lines
superset/themes/utils.py 16.66% 25 Missing ⚠️
superset/themes/schemas.py 69.23% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           master   #36317       +/-   ##
===========================================
+ Coverage        0   67.96%   +67.96%     
===========================================
  Files           0      636      +636     
  Lines           0    46858    +46858     
  Branches        0     5090     +5090     
===========================================
+ Hits            0    31848    +31848     
- Misses          0    13731    +13731     
- Partials        0     1279     +1279     
Flag Coverage Δ
hive 43.72% <20.00%> (?)
mysql 67.07% <35.55%> (?)
postgres 67.11% <35.55%> (?)
presto 47.33% <20.00%> (?)
python 67.93% <35.55%> (?)
sqlite 66.74% <35.55%> (?)
unit 100.00% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gabotorresruiz gabotorresruiz force-pushed the feat/add-custom-fonts-support branch 3 times, most recently from 5c24870 to e01d4a9 Compare November 29, 2025 17:08
@gabotorresruiz gabotorresruiz force-pushed the feat/add-custom-fonts-support branch from e01d4a9 to 69db2f0 Compare December 1, 2025 17:23
@sadpandajoe sadpandajoe added the 🎪 ⚡ showtime-trigger-start Create new ephemeral environment for this PR label Dec 1, 2025
@github-actions github-actions Bot added 🎪 69db2f0 🚦 building and removed 🎪 ⚡ showtime-trigger-start Create new ephemeral environment for this PR labels Dec 1, 2025
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 1, 2025

🎪 Showtime is building environment on GHA for 69db2f0

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates font loading from bundled npm packages to per-theme CDN-based loading, enabling flexible font customization for each theme configuration. The implementation removes @fontsource package dependencies in favor of dynamically loading fonts from Google Fonts and Adobe Fonts via theme fontUrls configuration.

Key changes:

  • Adds server-side validation for font URLs with domain whitelisting, HTTPS enforcement, and URL count limits
  • Implements client-side font loading via CSS @import with deduplication tracking
  • Updates CSP configuration to dynamically allow font domains from THEME_FONT_URL_ALLOWED_DOMAINS

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
superset/themes/utils.py Added validate_font_urls() and _validate_single_font_url() functions with comprehensive security validation
superset/themes/schemas.py Integrated font URL validation into theme schema validation workflow
superset/config.py Added fontUrls to default theme, removed CUSTOM_FONT_URLS, added THEME_FONTS_MAX_URLS and THEME_FONT_URL_ALLOWED_DOMAINS configs, updated CSP policies
tests/unit_tests/themes/test_utils.py Added comprehensive test coverage for font URL validation (15 test cases)
superset-frontend/src/theme/ThemeController.ts Added loadFonts() method with deduplication and secure CSS @import injection
superset-frontend/src/theme/tests/ThemeController.test.ts Added 7 test cases for font loading functionality
superset-frontend/packages/superset-core/src/ui/theme/types.ts Added fontUrls field to SupersetSpecificTokens interface with detailed JSDoc
superset-frontend/packages/superset-core/src/ui/theme/GlobalStyles.tsx Removed @fontsource imports
superset-frontend/packages/superset-ui-core/package.json Removed @fontsource/fira-code and @fontsource/inter dependencies
superset-frontend/packages/superset-core/package.json Removed @fontsource/fira-code and @fontsource/inter dependencies
superset/templates/superset/spa.html Removed CUSTOM_FONT_URLS template rendering

Comment thread superset/themes/utils.py
Comment thread superset/themes/utils.py
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Dec 1, 2025

🎪 Showtime deployed environment on GHA for 69db2f0

Environment: http://34.220.94.119:8080 (admin/admin)
Lifetime: 48h auto-cleanup
Updates: New commits create fresh environments automatically

Copy link
Copy Markdown
Member

@rusackas rusackas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Google fonts (or anything that hits Google) is NOT allowed by the ASF. This is why we're importing them through NPM, though I'm open to other NPM packages if they're better.

Copy link
Copy Markdown
Member

@rusackas rusackas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to make that last one a "request changes" rather than "approve" 🙈

@github-actions github-actions Bot added 🎪 🔒 showtime-blocked doc Namespace | Anything related to documentation and removed 🎪 🔒 showtime-blocked labels Dec 1, 2025
@gabotorresruiz
Copy link
Copy Markdown
Contributor Author

Hey @rusackas, awesome catch, thanks! I fixed that and cleaned up a couple of other things I spotted with @mistercrunch

Copy link
Copy Markdown
Member

@mistercrunch mistercrunch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Copy Markdown
Member

@rusackas rusackas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for the cleanup and making the ASF happy. I think this is good to go!

I see the doc changes are present in the current/next version AND in the 6.0.0 docs. I wasn't sure if I'd actually KEEP the 6.0.0 version in there (there's some small debate about it) but it seems A-OK to do it in both places, since theming docs are already there.

@rusackas rusackas merged commit 3940354 into apache:master Dec 9, 2025
70 checks passed
Facyla pushed a commit to Facyla/superset-contrib that referenced this pull request Dec 16, 2025
aminghadersohi pushed a commit to aminghadersohi/superset that referenced this pull request Jan 17, 2026
aminghadersohi pushed a commit to aminghadersohi/superset that referenced this pull request Jan 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies:npm doc Namespace | Anything related to documentation global:theming Related to theming Superset packages size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants