Laravel Magazine
Laravel's New @fonts Blade Directive Simplifies Web Font Loading

Laravel's New @fonts Blade Directive Simplifies Web Font Loading

Eric Van Johnson ·

Loading web fonts well has always involved more fiddly work than it should: registering the files with your bundler, writing @font-face rules, adding <link rel="preload"> tags in the right order, and remembering CSP nonces if you have a content security policy. A new addition to Laravel 13.x aims to collapse all of that into a single Blade directive.

What Landed

The feature is a new @fonts Blade directive backed by a font runtime in the Laravel Vite plugin, contributed by Wendell Adriel and merged into the framework. When you configure fonts, the Vite plugin resolves the requested font files, emits them as Vite assets, generates the font CSS, and writes a font manifest that the @fonts directive reads at render time.

In practice you drop the directive into the <head> of your root layout, and every configured font family gets a preload <link> plus an inline <style> block containing the @font-face rules and CSS custom properties. There is no manual asset wiring left to do.

<head>
    <meta charset="utf-8">
    @fonts
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

Configuring Your Fonts

Fonts are declared in vite.config.js. The Laravel Vite plugin ships provider helpers for Google Fonts, Bunny Fonts, Fontsource, and local font files, so you import the helper you want and pass it to the plugin's fonts option.

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import { google } from 'laravel-vite-plugin/fonts';

export default defineConfig({
    plugins: [
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            fonts: [
                google(['Inter:400,500,700', 'JetBrains Mono:400']),
            ],
        }),
    ],
});

If a particular page only needs a subset of your configured families, you can pass aliases to the directive so it renders just those:

@fonts('inter')

Why It Matters

There are three practical wins here. First, self-hosting Google or Bunny fonts becomes trivial, which keeps third-party requests out of your critical path and sidesteps a common privacy and GDPR concern. Second, the preload links are generated in the correct place, and the AddLinkHeadersForPreloadedAssets middleware picks up those preload entries for HTTP/2 server push automatically. Third, CSP nonce support is wired through the directive and facade, so applications running a strict content security policy do not have to hand-roll nonces onto inline font styles.

The directive supports optional family filtering, CSP nonces, preload attribute customization, and works in both build and hot (dev) modes. If you have ever copied a block of @font-face rules between projects, this is the feature that finally makes that unnecessary.

Availability

The @fonts directive and its supporting Vite runtime were merged into the laravel/framework and Laravel Vite plugin repositories for the Laravel 13.x line. If you are on Laravel 13, update to the latest release and the corresponding laravel-vite-plugin version to try it. As always, review the official Vite documentation for the exact configuration options available in your version.

Sources

Stay Updated

Subscribe to our newsletter

Get latest news, tutorials, community articles and podcast episodes delivered to your inbox.

Weekly articles
We send a new issue of the newsletter every week on Friday.
No spam
We'll never share your email address and you can opt out at any time.