fontaine
Automatically optimized font fallback based on font metrics
Nuxt Fontaine
Font metric fallback implementation for Nuxt 3
Features
⚠️ @nuxtjs/fontaine
is under active development. ⚠️
- 💪 Reduces CLS by using local font fallbacks with crafted font metrics.
- ✨ Generates font metrics and fallbacks automatically.
- ⚡️ Pure CSS, zero runtime overhead.
On the playground project, enabling/disabling this module makes the following differences rendering /
, with no customisation required:
Before | After | |
---|---|---|
CLS | 0.34 | 0.013 |
Performance | 88 | 98 |
What's next
For best performance, you will need to inline all your CSS, not just the font-face fallback rules (which this module does automatically), or there will still be a layout shift when the stylesheet loads (which is why the number above is not zero).
This PR aims to bring that ability to Nuxt itself.
Installation
With pnpm
pnpm add -D @nuxtjs/fontaine
Or, with npm
npm install -D @nuxtjs/fontaine
Or, with yarn
yarn add -D @nuxtjs/fontaine
Usage
export default defineNuxtConfig({ modules: ['@nuxtjs/fontaine'], // If you are using a Google font or you don't have a @font-face declaration // for a font you're using, you can declare them here. // // In most cases this is not necessary. // // fontMetrics: { // fonts: ['Inter', { family: 'Some Custom Font', src: '/path/to/custom/font.woff2' }], // },})
That's it!
How it works
Nuxt will scan your @font-face
rules and generate fallback rules with the correct metrics. For example:
@font-face { font-family: 'Roboto'; font-display: swap; src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff') format('woff'); font-weight: 700;}/* This will be generated. */@font-face { font-family: 'Roboto fallback'; src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local('Helvetica Neue'), local('Arial'), local('Noto Sans'); ascent-override: 92.7734375%; descent-override: 24.4140625%; line-gap-override: 0%;}
Then, whenever you use font-family: 'Roboto'
, Nuxt will add the fallback to the font-family:
:root { font-family: 'Roboto'; /* This becomes */ font-family: 'Roboto', 'Roboto fallback';}
Using outside of Nuxt
The core of this module will work outside of Nuxt, and has been separated into a separate library: fontaine
. Check it out!
💻 Development
- Clone this repository
- Enable Corepack using
corepack enable
(usenpm i -g corepack
for Node.js < 16.10) - Install dependencies using
pnpm install
- Stub module with
pnpm dev:prepare
- Run
pnpm dev
to start playground in development mode
Credits
This would not have been possible without:
- amazing tooling and generated metrics from capsizecss
- suggestion and algorithm from Katie Hempenius & Kara Erickson on the Google Aurora team - see notes on calculating font metric overrides.
License
Made with ❤️
Published under the MIT License.
Contributors 6