Provides :
- A fusion plugin that generates @font-faces and preloads fallback fonts based on app-level font configuration.
- A Higher Order Component for loading custom web fonts (and associated utils). During font loading, this HOC temporarily swaps the element to a well-matched fallback font, avoiding FOIT and FOUT. See https://www.zachleat.com/web/comprehensive-webfonts/#critical-foft-preload for more on this.
yarn add fusion-plugin-font-loading
// src/main.js
import App rom 'fusion-core';
import FontLoaderReactPlugin, {
FontLoaderReactConfigToken
} from 'fusion-plugin-font-loader-react';
export default () => {
const app = new App(<div></div>);
// ...
app.register(FontLoaderReactConfigToken, {/*some config*/});
app.register(FontLoaderReact);
// ...
return app;
}
// src/some-component.js
import {withFontLoading} from 'fusion-plugin-font-loader-react';
const FancyLink1 = withFontLoading('Lato-Bold'.(
styled('a', props => ({
':hover': {fontSize: `${props.answer}px`}.
...props.$fontStyles,
}))
);
Consuming apps should define a font-config.js
which a) provides data for @font-face generation, b) is used to derive the fallback font and styles that will be used by the with-font-loading.js
HOC.
Sample <app>/src/font-config.js file
import {assetUrl} from 'fusion-core';
export const preloadDepth = 1;
export const fonts = {
'Lato-Regular': {
urls: {
woff2: assetUrl('../static/Lato-Regular.woff2'),
},
fallback: {
name: 'Helvetica',
},
},
'Lato-Bold': {
urls: {
woff2: assetUrl('../static/Lato-Bold.woff2'),
},
fallback: {
name: 'Lato-Regular',
styles: {
'font-weight': 'bold',
},
},
},
'Lato-Thin': {
urls: {
woff2: assetUrl('./static/Lato-Thin.woff2'),
},
fallback: {
name: 'Lato-Regular',
styles: {
'font-weight': '100',
},
},
},
};
Based on the example configuration file above the following @font-face would be generated in
@font-face {font-family: "Lato-Regular"; src: url("/_static/ca614426b50ca7d007056aa00954764b.woff2") format("woff2");}
@font-face {font-family: "Lato-Bold"; src: url("/_static/ca104da8af9a2e0771e8fe2b31f8ec1e.woff2") format("woff2");}
@font-face {font-family: "Lato-Thin"; src: url("/_static/03b64805a8cd2d53fadc5814445c2fb5.woff2") format("woff2");}
- An in-memory font fallback tree is generated at runtime based on the defintitions provided in
font-config.js
- Fallbacks at and above the specified
preloadDepth
will be preloaded/prefetched on page load - Remaining fonts will lazily loaded.
Based on the sample config above (preloadDepth
is set to 1), the HOC example above would yield the following values for prop.$fontStyles
:
while loading font:
{
fontFamily: 'Lato-Regular'
fontWeight: 'bold'
}
when font is loaded:
{
fontFamily: 'Lato-Bold'
}
If preloadDepth
were 0 then every font would be preloaded, and there would be no fallback fonts
If preloadDepth
were 2 then the only fallback font would be Helvetica, and since Helvetica is a system font, no custom fonts would be preloaded.
This repo also supplies a with-font-loading.js
Higher Order Component which is used to:
- Load a specified font
- Temporarily assign a fallback font and styles to the wrapped component via
props.$fontStyles
- When the font is loaded assign the true font to child component via
props.$fontStyles
const FancyLink1 = withFontLoading('Lato-Bold'.(
styled('a', props => ({
':hover': {fontSize: `${props.answer}px`}.
...props.$fontStyles,
}))
);
This will lazy-load Lato-Bold
and meanwhile assign a fallback font and styling to the element via props.$fontStyles
.
Promise used by with-font-loading.js
HOC to dynamically load specified font; calls resolve
when load is complete.
Uses document.fonts.load
where available (chrome and firefox as of 10/17), otherwise uses a polyfill.