Bengal includes a built-in font management system that automatically downloads and hosts Google Fonts locally, improving performance and privacy.
Overview
The fonts system provides:
- Automatic font downloading from Google Fonts (no external dependencies)
- Self-hosting for better performance and GDPR compliance
- CSS generation with @font-face rules and CSS custom properties
- Zero configuration - just specify fonts in bengal.toml
Benefits:
- No external requests to Google Fonts CDN at runtime
- Faster page loads (fonts served from same domain)
- GDPR/privacy compliance (no third-party tracking)
- Offline builds
- Cache control
Font Downloader (bengal/fonts/downloader.py)
Purpose
Downloads font files from Google Fonts using the public CSS API.
Key Classes
| Class | Description |
|---|---|
GoogleFontsDownloader |
Downloads fonts from Google Fonts API |
FontVariant |
Represents a specific font variant (family + weight + style) |
Features
- No API key required
- Uses stdlib only (urllib)
- Automatic WOFF2 format selection (modern, smaller files)
- Supports multiple weights and styles
- SSL/TLS support
- Robust error handling
Usage
from bengal.fonts import GoogleFontsDownloader
from pathlib import Path
downloader = GoogleFontsDownloader()
# Download WOFF2 fonts for web use
variants = downloader.download_font(
family="Inter",
weights=[400, 600, 700],
styles=["normal", "italic"],
output_dir=Path("public/assets/fonts")
)
# Returns list of FontVariant objects with file info
TTF Downloads for Image Generation
For generating images with text (using Pillow), download TTF format:
# Download TTF fonts for Pillow image generation
ttf_variants = downloader.download_ttf_font(
family="Outfit",
weights=[400, 700],
output_dir=Path("assets/fonts")
)
# Returns variants with .ttf files instead of .woff2
Font CSS Generator (bengal/fonts/generator.py)
Purpose
Generates @font-face CSS rules for self-hosted fonts.
Key Classes
| Class | Description |
|---|---|
FontCSSGenerator |
Generates CSS with @font-face rules and custom properties |
Generated CSS includes
- @font-face declarations for each variant
- font-display: swap for performance
- CSS custom properties for easy reference
Example output
/* Inter */
@font-face {
font-family: 'Inter';
font-weight: 400;
font-style: normal;
font-display: swap;
src: url('fonts/inter-400.woff2') format('woff2');
}
@font-face {
font-family: 'Inter';
font-weight: 700;
font-style: normal;
font-display: swap;
src: url('fonts/inter-700.woff2') format('woff2');
}
/* CSS Custom Properties */
:root {
--font-primary: 'Inter';
--font-heading: 'Playfair Display';
}
Font Helper (bengal/fonts/__init__.py)
Purpose
Main interface that orchestrates downloading and CSS generation.
Key Classes
| Class | Description |
|---|---|
FontHelper |
Coordinates font downloading and CSS generation |
Usage
from bengal.fonts import FontHelper
helper = FontHelper(config['fonts'])
css_path = helper.process(assets_dir)
Configuration
Configure fonts inbengal.toml:
Simple format (family:weights)
[fonts]
primary = "Inter:400,600,700"
heading = "Playfair Display:700,900"
mono = "Fira Code:400,500"
Detailed format (with styles)
[fonts.primary]
family = "Inter"
weights = [400, 600, 700]
styles = ["normal", "italic"]
[fonts.heading]
family = "Playfair Display"
weights = [700, 900]
styles = ["normal"]
Build Integration
Fonts are automatically processed during builds:
- Font Helper runs early in build process
- Downloads fonts to
{output}/assets/fonts/ - Generates fonts.css in
{output}/assets/ - Theme can reference fonts via CSS custom properties
Output paths are relative to your configured output directory (typicallypublic/).
In theme CSS
body {
font-family: var(--font-primary), sans-serif;
}
h1, h2, h3 {
font-family: var(--font-heading), serif;
}
code {
font-family: var(--font-mono), monospace;
}
Health Validation
The FontValidator (bengal/health/validators/fonts.py) checks:
- Font files downloaded successfully
- fonts.css generated with valid @font-face rules
- File sizes reasonable (< 500KB per variant)
- All configured fonts present
- No broken font references in CSS
Font validation runs automatically during builds and reports issues to the console.
Performance Characteristics
File sizes: WOFF2 format typically 15-100KB per variant
Build overhead: Minimal - fonts cached locally after first download
Runtime performance: Eliminates external CDN requests
Comparison to Google Fonts CDN:
| Aspect | CDN | Self-hosted |
|---|---|---|
| Initial page load | External request | Same domain |
| Caching | Shared cache | Local cache |
| Privacy | Third-party | No tracking |
| Offline | Requires connection | Works offline |