Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Laravel Google Fonts
https://github.com/spatie/laravel-google-fonts
Admin
This package makes self-hosting Google Fonts frictionless for Laravel applications by scraping CSS,
...
Tokens:
11,442
Snippets:
50
Trust Score:
8.5
Update:
3 months ago
Context
Skills
Chat
Benchmark
67.5
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Laravel Google Fonts This Laravel package enables self-hosting Google Fonts with minimal friction, eliminating the need for external DNS lookups and reducing privacy concerns. When fonts are requested for the first time, the package automatically scrapes the CSS from Google Fonts, downloads the font files, stores them locally, and serves them inline or via local URLs. The package handles WOFF2 font formats, supports multiple font configurations, and provides automatic fallback to Google's CDN if local hosting fails. The core functionality revolves around a Blade directive `@googlefonts` that intelligently manages font loading. Fonts are stored in Laravel's filesystem (default: public disk), and the package automatically localizes all font URLs in the CSS. It supports CSP nonce attributes for security, preload tags for performance optimization, and customizable user agents for controlling which font formats are downloaded from Google's servers. ## APIs and Key Functions ### @googlefonts Blade Directive Renders Google Fonts in Blade templates by loading configured fonts from local storage or fetching them from Google Fonts API on first use. ```blade {{-- resources/views/layouts/app.blade.php --}} <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My Application</title> {{-- Load the default font (Inter) inline --}} @googlefonts {{-- Load a named font configuration (IBM Plex Mono for code) --}} @googlefonts('code') {{-- Load with CSP nonce for Content Security Policy --}} @googlefonts(['nonce' => csp_nonce()]) {{-- Load named font with nonce --}} @googlefonts(['font' => 'code', 'nonce' => csp_nonce()]) </head> <body> <h1 style="font-family: 'Inter', sans-serif;">Welcome</h1> <code style="font-family: 'IBM Plex Mono', monospace;">const hello = 'world';</code> </body> </html> ``` ### Configuration Setup Define Google Fonts URLs and package behavior in the configuration file to control font loading, storage, and rendering. ```php <?php // config/google-fonts.php return [ // Register fonts with unique keys 'fonts' => [ 'default' => 'https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,700;1,400;1,700&display=swap', 'code' => 'https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,700;1,400&display=swap', 'display' => 'https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700;900&display=swap', ], // Storage disk (must be publicly accessible) 'disk' => 'public', // Path prefix for font files 'path' => 'fonts', // Inline CSS to reduce HTTP requests (true) or use <link> tag (false) 'inline' => true, // Generate preload tags for faster font loading 'preload' => false, // Fallback to Google's CDN on errors (disable in debug mode to see exceptions) 'fallback' => ! env('APP_DEBUG'), // User agent determines font format (WOFF2, WOFF, TTF, etc.) 'user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15', ]; ``` ### GoogleFonts::load() Method Loads a font configuration and returns a Fonts object with methods for rendering HTML tags or retrieving URLs. ```php <?php // In a controller or service class use Spatie\GoogleFonts\GoogleFonts; class FontService { public function __construct(private GoogleFonts $googleFonts) { } public function loadFonts(): array { // Load default font $defaultFonts = $this->googleFonts->load(); // Load named font $codeFonts = $this->googleFonts->load('code'); // Load with options array $secureFonts = $this->googleFonts->load([ 'font' => 'display', 'nonce' => 'random-nonce-value' ]); // Force re-download (useful for updates) $freshFonts = $this->googleFonts->load('default', forceDownload: true); return [ 'default_inline' => (string) $defaultFonts->inline(), 'code_link' => (string) $codeFonts->link(), 'display_url' => $secureFonts->url(), 'fallback' => (string) $freshFonts->fallback(), ]; } } ``` ### Fonts Rendering Methods The Fonts class provides multiple rendering options for including font stylesheets in HTML with different strategies. ```php <?php use Spatie\GoogleFonts\GoogleFonts; $fonts = app(GoogleFonts::class)->load('default'); // Inline CSS (fastest, no additional HTTP request) $inlineHtml = $fonts->inline(); // Output: <style>@font-face { font-family: 'Inter'; src: url('...'); }</style> // External stylesheet link $linkHtml = $fonts->link(); // Output: <link href="https://example.com/storage/fonts/952ee985ef/fonts.css" rel="stylesheet" type="text/css"> // Fallback to Google's CDN (used when local hosting fails) $fallbackHtml = $fonts->fallback(); // Output: <link href="https://fonts.googleapis.com/css2?family=Inter..." rel="stylesheet" type="text/css"> // Get direct URL to local CSS file $cssUrl = $fonts->url(); // Output: https://example.com/storage/fonts/952ee985ef/fonts.css // Automatic rendering based on config (inline or link) $autoHtml = $fonts->toHtml(); // Output depends on 'inline' config setting // With nonce for Content Security Policy $secureInline = app(GoogleFonts::class)->load(['font' => 'default', 'nonce' => 'abc123'])->inline(); // Output: <style nonce="abc123">@font-face { ... }</style> echo $inlineHtml; ``` ### Artisan Command: google-fonts:fetch Pre-download all configured fonts to local storage before deployment or during build process to avoid first-request delays. ```bash # Fetch all fonts defined in config/google-fonts.php php artisan google-fonts:fetch # Example output: # Start fetching Google Fonts... # Fetching `default`... # Fetching `code`... # Fetching `display`... # All done! # Integrate into deployment script cat > deploy.sh << 'EOF' #!/bin/bash composer install --no-dev --optimize-autoloader php artisan config:cache php artisan route:cache php artisan view:cache php artisan google-fonts:fetch php artisan storage:link EOF # Use in CI/CD pipeline (GitHub Actions example) cat > .github/workflows/deploy.yml << 'EOF' name: Deploy on: [push] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Install dependencies run: composer install - name: Cache Google Fonts run: php artisan google-fonts:fetch - name: Deploy to server run: ./deploy.sh EOF ``` ### Package Installation Install and configure the package in a Laravel application with optional configuration publishing. ```bash # Install via Composer composer require spatie/laravel-google-fonts # Publish configuration file (optional) php artisan vendor:publish --provider="Spatie\GoogleFonts\GoogleFontsServiceProvider" --tag="google-fonts-config" # Create storage link for public disk php artisan storage:link # Verify storage/app/public/fonts directory is writable ls -la storage/app/public/ # Test font loading in tinker php artisan tinker >>> app(\Spatie\GoogleFonts\GoogleFonts::class)->load('default'); >>> exit ``` ### Advanced Configuration Examples Customize font loading behavior for different environments, CDN hosting, and legacy browser support. ```php <?php // config/google-fonts.php return [ 'fonts' => [ 'default' => 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap', 'headings' => 'https://fonts.googleapis.com/css2?family=Montserrat:wght@600;700;800&display=swap', ], // Use custom disk for CDN deployment 'disk' => env('GOOGLE_FONTS_DISK', 'public'), // Custom path for multi-tenant applications 'path' => 'assets/fonts/' . config('app.tenant_id'), // External links in production, inline in development 'inline' => env('APP_ENV') === 'local', // Enable preload in production only 'preload' => env('APP_ENV') === 'production', // Always fallback in production, throw exceptions in development 'fallback' => env('APP_ENV') === 'production', // Legacy browser support (WOFF instead of WOFF2) 'user_agent' => env('LEGACY_BROWSER_SUPPORT', false) ? 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Safari/605.1.15', ]; ``` ### Custom Disk Configuration for CDN Configure a custom filesystem disk to serve fonts from a CDN like AWS CloudFront or DigitalOcean Spaces. ```php <?php // config/filesystems.php 'disks' => [ // ... other disks 'fonts-cdn' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_FONTS_BUCKET'), 'url' => env('AWS_CLOUDFRONT_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'visibility' => 'public', ], ], // config/google-fonts.php return [ 'disk' => 'fonts-cdn', 'path' => 'fonts', 'inline' => false, // Use links for CDN 'preload' => true, // Preload from CDN // ... other settings ]; ``` ### Programmatic Font Loading in Services Use the GoogleFonts service directly in application code for dynamic font management or API responses. ```php <?php namespace App\Services; use Spatie\GoogleFonts\GoogleFonts; use Illuminate\Support\Facades\Cache; class ThemeService { public function __construct(private GoogleFonts $googleFonts) { } public function getThemeFonts(string $theme): string { $fontKey = match($theme) { 'modern' => 'default', 'classic' => 'display', 'code' => 'code', default => 'default', }; return Cache::remember("theme_font_{$theme}", 3600, function () use ($fontKey) { try { $fonts = $this->googleFonts->load($fontKey); return (string) $fonts->inline(); } catch (\Exception $e) { report($e); return $this->googleFonts->load($fontKey)->fallback(); } }); } public function preloadAllThemeFonts(): void { $themes = ['modern', 'classic', 'code']; foreach ($themes as $theme) { $fontKey = match($theme) { 'modern' => 'default', 'classic' => 'display', 'code' => 'code', }; $this->googleFonts->load($fontKey, forceDownload: true); } } } ``` ### Testing Font Loading Example test cases demonstrating font loading verification and snapshot testing for rendered output. ```php <?php namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Storage; use Spatie\GoogleFonts\GoogleFonts; use Tests\TestCase; class GoogleFontsTest extends TestCase { protected function setUp(): void { parent::setUp(); Storage::fake('public'); } public function test_loads_fonts_and_stores_locally(): void { $fonts = app(GoogleFonts::class)->load('default', forceDownload: true); // Verify CSS file exists Storage::disk('public')->assertExists('fonts/952ee985ef/fonts.css'); // Verify font files downloaded $files = Storage::disk('public')->allFiles('fonts/952ee985ef'); $woff2Files = array_filter($files, fn($f) => str_ends_with($f, '.woff2')); $this->assertGreaterThan(0, count($woff2Files)); // Verify HTML output $inlineHtml = (string) $fonts->inline(); $this->assertStringContainsString('<style>', $inlineHtml); $this->assertStringContainsString('@font-face', $inlineHtml); $linkHtml = (string) $fonts->link(); $this->assertStringContainsString('<link', $linkHtml); $this->assertStringContainsString('rel="stylesheet"', $linkHtml); } public function test_falls_back_to_google_on_error(): void { config()->set('google-fonts.fonts', ['test' => 'invalid-url']); config()->set('google-fonts.fallback', true); $fonts = app(GoogleFonts::class)->load('test', forceDownload: true); $html = (string) $fonts->toHtml(); $this->assertStringContainsString('invalid-url', $html); } public function test_adds_nonce_attribute(): void { $fonts = app(GoogleFonts::class)->load([ 'font' => 'default', 'nonce' => 'test-nonce-123' ]); $inlineHtml = (string) $fonts->inline(); $this->assertStringContainsString('nonce="test-nonce-123"', $inlineHtml); } } ``` ## Summary This package serves Laravel developers who want to self-host Google Fonts for improved page load performance and enhanced privacy compliance. Primary use cases include production applications requiring GDPR compliance, sites optimizing Core Web Vitals metrics, and projects that need offline font availability. The package automatically handles font downloading, CSS localization, and intelligent caching without requiring manual font file management. Integration patterns include using the `@googlefonts` Blade directive for immediate templating needs, pre-fetching fonts during deployment with the Artisan command, and programmatic font management through the GoogleFonts service class for dynamic themes or multi-tenant applications. The package seamlessly integrates with Laravel's filesystem abstraction, supports CDN deployment through custom disk configurations, and provides CSP nonce support for security-conscious applications. Error handling with automatic fallback ensures reliability while the inline CSS option eliminates render-blocking requests for optimal performance.