Table of Contents & Menu
Navigation

Using custom fonts with Hyvä

Several methods exist for including custom fonts in your theme. While all work, careless implementation can negatively impact Google ranking metrics.

Performance impact varies based on the inclusion method, server, and caching configuration.

Generally, performance differences between options are minimal and often fall within normal Pagespeed fluctuations.

Tailwind configuration

After adding your font files, declare the font-family in your CSS, e.g., font-family: 'Roboto', sans-serif;.

To use with Tailwind, add the font to `tailwind.config.js`. Refer to the Tailwind documentation for various declaration approaches. Here's an example for `font-sans`:

theme: {
    extend: {
        fontFamily: {
            sans: ['Roboto', ...defaultTheme.fontFamily.sans]
        }
    }
}

Import the `defaultTheme` object by adding the following to the top of the file:

const defaultTheme = require('tailwindcss/defaultTheme');

Google fonts

When selecting a Google Font from fonts.google.com, you'll see a default implementation:

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">

Include a slightly altered version in `Magento_Theme/layout/default_head_blocks.xml`. Note the HTML `&amp;` notation for the ampersand in the URL.

<link src="https://fonts.googleapis.com/css2?family=Roboto&amp;display=swap" rel="stylesheet" type="text/css" src_type="url"/>

To add preconnect resources, include a custom block in the head, for example:

<referenceBlock name="head.additional">
    <block class="Magento\Framework\View\Element\Text" name="custom.fonts">
        <arguments>
            <argument name="text" xsi:type="string">
                <![CDATA[
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
                ]]>
            </argument>
        </arguments>
    </block>
</referenceBlock>

Using Google fonts from Google servers

Be careful when using Google fonts from the Google servers, since that is by default not compliant with the GDPR.
German websites have been fined for using automatically requested Google fonts.
To use the Google font files locally, use this helper to quickly select the desired formats and download the files and code. See further on how to include the local files.

Local font files

Use custom or downloaded Google Font files locally from your web server. Register them using `@font-face` CSS rules, referencing their file locations.

Example:

@font-face {
    font-family: 'Roboto';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/roboto.woff2') format('woff2');
}

Each font variant (e.g., different weights, styles) requires its own `@font-face` declaration. These declarations register the font but don't load it automatically; the font loads only when used via a `font-family` CSS property (e.g., `font-family: "Roboto";`) or a Tailwind class.

While older formats like `.ttf`, `.otf`, and `.eot` exist, it's now recommended to use only `woff2` or `woff` files.

Place font files in your theme's `web/fonts/` folder.

Add `@font-face` styles to a CSS file, such as `web/tailwind/components/typography.css`.

Ensure correct font file paths. Since the generated CSS is in `web/css`, `../fonts/` refers to `web/fonts/`.

Preloading/preconnect

Preloading fonts

It is often recommended to preload fonts that are used above the fold to ensure the fastest possible delivery.
This helps avoid layout shifts, however doing so impacts the LCP, since preloading fonts blocks the first render.

To avoid layout shifts, instead set the right system fallback fonts and line-heights (reserve space).
You can also use size-adjust and ascent-override on the fallback font, and you can calculate these dynamically for some fonts (for example the Google ones).

If you choose to preload fonts despite the warning, proceed as follows:
Preload local fonts by adding this snippet to the `` section of your `Magento_Theme/layout/default_head_blocks.xml` file:

<font src="fonts/roboto.woff2"/>

This preloads the specified URL. For multiple font formats, `preconnect` is preferred. Use a custom block for this:

<referenceBlock name="head.additional">
    <block
        class="Magento\Framework\View\Element\Template" 
        name="custom.fonts"
        template="Magento_Theme::head.phtml"
    />
</referenceBlock>

In `head.phtml`, use something like:

<link rel="preconnect" href="<?= $block->getViewFileUrl('fonts/roboto.woff2') ?>">

Opinions on preloading vary. Test your environment to ensure the desired outcome.

Font-display options

The `swap` value for `font-display` is generally recommended. It prioritizes fast text display, loading the webfont eventually. Rapid loading is crucial to prevent layout shifts. The `optional` value prevents the webfont from displaying if it loads too slowly.

Other options may be suitable depending on your specific needs.

PostCSS plugin

Alternatively, use the postcss-font-magician Node.js package. Add your font file locations to the PostCSS config, and styles will be automatically added to `styles.css`. Example:

require('postcss-font-magician')({
   hosted: ['../fonts/', '../fonts']
})

Further in-depth information

For general font best practices, refer to Best practices for fonts on web.dev.