[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [![Github Actions][github-actions-src]][github-actions-href] [![Codecov][codecov-src]][codecov-href]
npm install @nuxtjs/fontaine[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![Github Actions][github-actions-src]][github-actions-href]
[![Codecov][codecov-src]][codecov-href]
> Font metric fallback implementation for Nuxt 3
- ✨ Changelog
- ▶️ Online playground
⚠️ @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 |
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.
``bash`
npx nuxi@latest module add fontaine
`js`
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!
If you use Tailwind CSS and use your custom font via the config file, you will need to manually add the fallback font.
`ts
import type { Config } from 'tailwindcss'
import { fontFamily } from 'tailwindcss/defaultTheme'
export default
theme: {
extend: {
fontFamily: {
sans: ['Roboto', 'Roboto fallback', ...fontFamily.sans],
},
},
},
}
`
Nuxt will scan your @font-face rules and generate fallback rules with the correct metrics. For example:
`css`
@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('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:
`css`
:root {
font-family: 'Roboto';
/ This becomes /
font-family: 'Roboto', 'Roboto fallback';
}
The core of this module will work outside of Nuxt, and has been separated into a separate library: fontaine. Check it out!
- Clone this repository
- Enable Corepack using corepack enablepnpm install
- Install dependencies using pnpm dev:prepare
- Stub module with pnpm dev` to start playground in development mode
- Run
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.
Made with ❤️
Published under the MIT License.
[npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/fontaine?style=flat-square
[npm-version-href]: https://npmjs.com/package/@nuxtjs/fontaine
[npm-downloads-src]: https://img.shields.io/npm/dm/@nuxtjs/fontaine?style=flat-square
[npm-downloads-href]: https://npm.chart.dev/@nuxtjs/fontaine
[github-actions-src]: https://img.shields.io/github/workflow/status/nuxt-modules/fontaine/ci/main?style=flat-square
[github-actions-href]: https://github.com/nuxt-modules/fontaine/actions/workflows/ci.yml
[codecov-src]: https://img.shields.io/codecov/c/gh/nuxt-modules/fontaine/main?style=flat-square
[codecov-href]: https://codecov.io/gh/nuxt-modules/fontaine