Weave 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 Webfonts Laravel Package

log1x/laravel-webfonts

Self-host Google Fonts in Laravel with a simple artisan command. laravel-webfonts downloads the font files you need, generates local CSS, and gives you a Blade component for fast, privacy-friendly typography without third-party requests.

View on GitHub
Deep Wiki
Context7

Getting Started

log1x/laravel-webfonts self-hosts Google Fonts so your app never hits fonts.googleapis.com / fonts.gstatic.com at runtime. Expect it to be the first thing you reach for when a client flags GDPR/privacy concerns or when Lighthouse complains about render-blocking third-party font requests.

Minimal path:

  1. composer require log1x/laravel-webfonts
  2. Publish the config + asset scaffolding: php artisan vendor:publish --provider="Log1x\Webfonts\WebfontsServiceProvider"
  3. Open config/webfonts.php. Every font is a named alias (e.g. inter, display, mono) with a family, weights, and optionally styles/subsets. Aliases are what you reference everywhere else, so name them by role, not by family — sans, heading, mono — and you can swap the underlying family later without touching views.
  4. Download the files: php artisan webfonts:fetch. This writes the font binaries plus a generated stylesheet into the configured public path.
  5. Load a font in AppServiceProvider::boot() with the Webfonts facade, and drop the Blade directive into your layout head:
    {{-- resources/views/layouts/app.blade.php --}}
    <head>
        @webfonts
    </head>
    
    // app/Providers/AppServiceProvider.php
    public function boot(): void
    {
        Webfonts::load('sans');
    }
    

First real use case: pick one family, define it in config, fetch, load it in the provider, output @webfonts, then delete the <link> tags to Google from your layout and confirm in the network tab that no request leaves your domain.

What's new in 2.0.1: preloading is now selectable per font rather than all-or-nothing. If you previously accepted either "no preload" or "preload everything," you can now set a preload list in config/webfonts.php naming only the aliases (and, depending on your config shape, the weights) you want emitted as <link rel="preload" as="font" ... crossorigin>. Re-publish or diff the config stub after upgrading to see the new key.

Implementation Patterns

Where to load fonts. Two options, and the package doesn't stop you from using both:

  • Provider-level (Webfonts::load('sans')) — the font is available on every response, including Livewire/Inertia partials that reload the <head>. Best for a global brand font.
  • Directive-level with arguments — load only what a given layout needs. Useful for a marketing page that uses a display face the app shell doesn't.

Pick one per page. Mixing both produces duplicate <link> output, which browsers tolerate but which bloats HTML and makes auditing harder.

Preload deliberately (the 2.0.1 pattern). Preload is a bandwidth commitment, not a performance switch. The idiomatic setup:

  • Preload the single weight/style that paints above-the-fold content (usually 400 normal, sometimes a 600/700 for headings).
  • Do not preload the full stack of weights, italics, or Cyrillic/Greek subsets the page may never render.
  • Keep font-display: swap in place so a slow or failed preload doesn't block first paint — a preloaded font that arrives late is worse than one that arrives on demand.

Typical config shape:

// config/webfonts.php
return [
    'path'  => public_path('fonts'),
    'fonts' => [
        'sans'    => ['family' => 'Inter',  'weights' => [400, 500, 700]],
        'display' => ['family' => 'Fraunces', 'weights' => [700]],
    ],
    'preload' => ['sans'],   // only Inter 400 ships in the critical path
];

Pair it with your build. The generated CSS declares font-family names that must match whatever Tailwind/Vite config or plain CSS you write. Decide the canonical names once (config family string) and reference them in tailwind.config.js theme.fontFamily, then add the local font files to your Tailwind content/asset audit so nobody reintroduces a @import url('https://fonts.googleapis.com/...') in a stylesheet by accident.

Deployment. webfonts:fetch needs outbound network access, so:

  • Committed fonts (recommended for most teams): run webfonts:fetch locally once, commit the generated files under public/fonts, and never run the command in CI. Deterministic builds, no external dependency, easy code review of binary changes.
  • Fetched at build/deploy: run webfonts:fetch in your deploy script after composer install. Faster repo, but your pipeline now depends on Google's API being reachable and stable. Add it before asset cache warming so the generated CSS is present when Vite's manifest is read.

Per-enforcement / local overrides. The same alias mechanism lets you ship a licensed self-hosted font (place files in the configured path and register them) alongside fetched Google Fonts — handy when a design system mixes both.

Gotchas and Tips

  • Configuration is cached. After changing fonts or preload, run php artisan config:clear. The fetch command reads the cached config in some setups, so a stale cache silently produces the old font set. This is the single most common "it isn't picking up my change" cause.
  • Re-fetch after any config change. Adding a weight only to config/webfonts.php does nothing — the binaries and generated CSS are artefacts of the last webfonts:fetch. Treat the fetch step as a build step, not a one-time install.
  • Preload is not transitive. Listing an alias in preload doesn't verify that the weight you preload is actually in that alias's weights array. A preload for a weight you never fetched produces a console warning and a wasted request. Cross-check both lists.
  • Permissions. webfonts:fetch writes into public/. In containerised deploys where public/ is bind-mounted read-only at runtime, run the fetch during the build stage, not on boot.
  • Avoid double-emitting the directive. If the directive lives in a component that renders more than once per page (e.g. an error layout and the main layout both extend a head partial), you get repeated <link>s. Put @webfonts in exactly one head partial.
  • Debugging missing glyphs. If text renders in a fallback face, check (a) the generated CSS is actually served — view source, follow the href; (b) the alias was loaded in the provider for that request; (c) the weight/style combination you typed in CSS exists in the fetched set. The generated stylesheet is small and readable; open it before you start guessing.
  • Extension points. The service provider publishes both config and views, so the font <link> markup is overridable — publish views if you need to inject crossorigin, integrity, or a custom media attribute. For programmatic control (e.g. deciding preload targets per-request based on the route), skip the directive and render the tags yourself using the facade's asset lookup.
  • Licensing nuance. The package fetches the files; it doesn't audit licences. Most Google Fonts are OFL and fine to redistribute in a repo, but confirm per-family before committing binaries to a public repository.
  • Upgrade note. 2.0.1 is additive — a feature release on the 2.0 line, no deprecations. Safe drop-in from 2.0.0. Existing setups that don't define the new preload setting keep their previous output, so treat it as opt-in rather than something that silently changes your critical path.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo