Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Google Fonts Laravel Package

spatie/laravel-google-fonts

Self-host Google Fonts in Laravel with minimal setup. Register Google Fonts CSS URLs in config and load them via the @googlefonts Blade directive. On first request it downloads CSS/assets, caches locally, inlines CSS, and falls back to Google if needed.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require spatie/laravel-google-fonts
    php artisan vendor:publish --provider="Spatie\GoogleFonts\GoogleFontsServiceProvider" --tag="google-fonts-config"
    
    • Publishes the config/google-fonts.php file with default settings.
  2. Configure Fonts Add your Google Font embed URLs to the fonts array in config/google-fonts.php:

    'fonts' => [
        'default' => 'https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap',
        'secondary' => 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400&display=swap',
    ],
    
  3. First Use Case Load fonts in a Blade view using the @googlefonts directive:

    <head>
        @googlefonts  <!-- Loads 'default' font -->
        @googlefonts('secondary')  <!-- Loads 'secondary' font -->
    </head>
    
  4. Prefetch Fonts (Optional) Run the Artisan command to pre-download fonts for immediate availability:

    php artisan google-fonts:fetch
    

Implementation Patterns

Core Workflows

  1. Font Registration & Usage

    • Register fonts in config/google-fonts.php with descriptive keys (e.g., default, code).
    • Use @googlefonts('key') in Blade templates to load specific fonts.
    • Default font loads automatically with @googlefonts (no argument).
  2. Dynamic Font Loading

    • Pass an array to @googlefonts for advanced options (e.g., CSP nonces):
      @googlefonts(['font' => 'secondary', 'nonce' => csp_nonce()])
      
  3. Prefetching Strategy

    • Eager Loading: Run php artisan google-fonts:fetch during deployment to pre-download all fonts.
    • Lazy Loading: Enable lazy mode (v1.6+) by modifying the GoogleFontsManager service provider to defer fetching until first request:
      // In a service provider or config
      $this->app->singleton(GoogleFontsManager::class, function ($app) {
          return new GoogleFontsManager($app['config'], $app['files'], $app['cache'], true); // true = lazy
      });
      
  4. Integration with CSP

    • Use the nonce option to comply with Content Security Policy (CSP):
      @googlefonts(['nonce' => csp_nonce()])
      
  5. Multi-Environment Setup

    • Override font URLs per environment (e.g., config/google-fonts.php):
      'fonts' => [
          env('APP_ENV') === 'production'
              ? 'production_url_here'
              : 'development_url_here',
      ],
      

Advanced Patterns

  1. Custom Disk/Path Configuration

    • Store fonts in a custom disk (e.g., S3) or path:
      'disk' => 's3',
      'path' => 'custom-fonts-path',
      
    • Ensure the disk is linked or configured for public access.
  2. Fallback Behavior

    • Disable fallback to Google’s CDN in config/google-fonts.php:
      'fallback' => false, // Throws exceptions on failure (debug mode only)
      
    • Handle exceptions in a global exception handler or middleware.
  3. Conditional Font Loading

    • Use Blade directives conditionally:
      @if(auth()->check())
          @googlefonts('premium-font')
      @endif
      
  4. Local Development Optimization

    • Disable inlining for faster development iteration:
      'inline' => env('APP_ENV') === 'local' ? false : true,
      
  5. Font Preloading

    • Enable preload tags for critical fonts:
      'preload' => true,
      
    • Preload tags are automatically generated for fonts with preload: true.

Gotchas and Tips

Pitfalls

  1. Storage Link Requirement

    • Issue: Fonts fail to load with 404 errors.
    • Fix: Run php artisan storage:link to symlink storage/app/public to public/storage.
    • Note: If using a custom disk/path, ensure the directory is accessible via HTTP.
  2. User Agent Limitations

    • Issue: Legacy browsers (e.g., IE) may not support WOFF2 fonts.
    • Fix: Override the user_agent in config to target older formats:
      'user_agent' => 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)',
      
    • Tradeoff: Increases payload size for modern browsers.
  3. Caching Quirks

    • Issue: Changes to font URLs/config aren’t reflected immediately.
    • Fix: Clear the cache:
      php artisan cache:clear
      php artisan view:clear
      
    • Tip: Use php artisan google-fonts:fetch --force to re-fetch fonts.
  4. Duplicate Font URLs

    • Issue: Multiple entries with the same URL may cause conflicts.
    • Fix: The package deduplicates URLs internally, but ensure config entries are unique.
  5. Nonce Mismatches

    • Issue: CSP blocks font loading despite correct nonce usage.
    • Fix: Verify the nonce matches the CSP directive:
      @googlefonts(['nonce' => csp_nonce()])
      
      // In CSP middleware
      $directive->addStyleSources(['nonce' => csp_nonce()]);
      
  6. Git Ignore Conflicts

    • Issue: storage/app/public/fonts is ignored by .gitignore.
    • Fix: Exclude the directory from .gitignore if you want to version-control fonts:
      !/storage/app/public/fonts/
      

Debugging Tips

  1. Check Fetch Logs

    • Enable debug mode to log fetch operations:
      'fallback' => true, // Logs errors to Laravel logs
      
    • Inspect logs at storage/logs/laravel.log.
  2. Verify Font Files

    • Manually check if fonts exist in storage/app/public/fonts after running google-fonts:fetch.
    • Use php artisan storage:link if files are missing in public/storage/fonts.
  3. Test Fallback Behavior

    • Temporarily disable the package to test fallback:
      // In AppServiceProvider
      $this->app->bind(GoogleFontsManager::class, function () {
          return new class {
              public function render($font = null) { return '<link href="https://fonts.googleapis.com/..." rel="stylesheet">'; }
          };
      });
      
  4. Inspect Blade Output

    • Use @dd to debug the directive’s output:
      @googlefonts(['font' => 'test'])
      @dd($__env->yieldContent('googlefonts'))
      

Extension Points

  1. Custom Fetch Logic

    • Override the GoogleFontsManager to implement custom fetching (e.g., proxy requests):
      $manager->setFontFetcher(new CustomFontFetcher());
      
  2. Dynamic Font Registration

    • Register fonts programmatically via a service provider:
      $config = config('google-fonts.fonts');
      $config['dynamic-font'] = 'https://fonts.googleapis.com/...';
      config(['google-fonts.fonts' => $config]);
      
  3. Post-Fetch Processing

    • Extend the FontFetcher to modify downloaded files (e.g., optimize WOFF2):
      use Spatie\GoogleFonts\FontFetcher;
      
      class CustomFontFetcher extends FontFetcher {
          protected function processFontFile($contents, $url) {
              // Custom logic (e.g., compression)
              return parent::processFontFile($contents, $url);
          }
      }
      
  4. Event Listeners

    • Listen for font fetch events to log or analyze usage:
      use Spatie\GoogleFonts\Events\FontsFetched;
      
      FontsFetched::listen(function (FontsFetched $event) {
          Log::info('Fetched fonts:', $event->fonts);
      });
      
  5. Conditional Inlining

    • Dynamically toggle inlining based on request context (e.g., mobile devices):
      'inline' => function () {
          return !request()->isMobile();
      },
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai