Web fonts
Loading custom fonts in a performant way can be hard. Flight framework
components to make this as simple as possible — GoogleFont
, TypekitFont
,
and CustomFont
.
We have implemented the FOUT with class method for loading webfonts. You can read more about this method here: https://www.zachleat.com/web/comprehensive-webfonts/#fout-class
Essentially, we load your fonts asynchronously so that rendering is not
blocked. This means that text is visible sooner, which improves the perceived
performance of the app. Once the fonts have loaded, we add a className to the
html
element in the form your-font-name-ready
. You can then use this
className in your styles to apply the font. We do this automatically for your
primaryFont
. More on this later!
Common props
Each of the font components accepts a primaryFont
and a secondaryFonts
prop, described below.
/**
* The Primary font used in the app. This will be added to the `body` styles.
* If you use multiple Font components, only one should use primaryFont. A
* `font-family-name-ready` class will also be added to the html tag. */
type primaryFont = string;
/**
* An array of secondary fonts used in your app. For each of these fonts, a
* class will be added to the html element in the form `font-family-name-ready`
* once the font is loaded and ready to use */
type secondaryFonts = string[];
primaryFont
The primaryFont
will be automatically applied to the body. It will be used
for all text by default. The CSS used to apply the font is as follows
(font-family-name and Font Family Name will be substituted):
/** These styles are automatically applied for the `primaryFont` **/
.font-family-name-ready body {
font-family: "Font Family Name", sans-serif;
line-height: 1;
letter-spacing: 0;
word-spacing: 0;
font-weight: normal;
}
secondaryFonts
Any fonts supplied to the secondaryFonts
array will not automatically
generate any CSS, but they will be added to the html
tag, so they can be
applied selectively.
For example, let's say that you want to use Lato for all headers on your
site. If you supply this font to secondaryFonts
, the className lato-ready
will be added to the html
tag. You could then use it like so:
.lato-ready h1,
.lato-ready h2,
.lato-ready h3,
.lato-ready h4 {
font-family: "Lato", sans-serif;
}
Fallback styles
import webfontComparison from '@root/docs/static/webfont-comparison.png'; import layoutShift from '@root/docs/static/layout-shift.gif';
Until your fonts have finished loading, fallback font styles will be used.
You can define the fallback styles in your Theme.js
(example at
template-trend/src/components/Theme.js
).
To minimise the flash of unstyled text (FOUC) when the fallback font swaps to
the desired font, you should choose fallback styles that most closely match
the primaryFont
you are using. A good tool to do this is this Font Style
Matcher.
<img src={webfontComparison} style={{ maxWidth: '100%', boxShadow: '0 0 18px rgba(0,0,0,0.2)', borderRadius: '6px' }} />
On the right, select or upload your primaryFont
. On the left, select a
system font that roughly matches (for example, system-ui
or Helvetica
).
You can then adjust the fallback font using the sliders to most closely match
it to your desired webfont. Copy the fallback font styles to your Theme.js
.
Example of matched fonts:
<img src={layoutShift} style={{ maxWidth: '100%' }} />
Custom Fonts
The CustomFont
component (@jetshop/core/components/Fonts/CustomFont
) is
the recommended way of delivering fonts. With this method, you will need to
provide the fonts yourself by putting them in the fonts
directory in your
template. There is an example of this in Template Trend.
You will also need to provide your own @font-face
declarations. Again,
there is an example of this in Template Trend at
template-trend/src/fonts/loadFontCss.js
. If you want to use the free fonts
offered by Google, you can download the font files at
http://google-webfonts-helper.herokuapp.com. For other fonts, you are
responsible for providing properly licensed font files.
As demonstrated in loadFontCss.js
, import each of your fonts and then use
the import name in your @font-face
declarations. We've included an example
of how to provide different font formats in order to maximise browser
compatibility. If you only need to support modern browsers, you can just
include woff2 and woff. Make sure to include font-display: swap
in your
declarations.
Usage
In your Shop.js
, include the CustomFont
component. Pass it a
primaryFont
and/or secondaryFonts
(as described under Common props
above), along with an injectCss
prop containing the method containing your
@font-face
declarations imported from loadFontCss.js
.
<CustomFont primaryFont="Lato" injectCss={loadFontCss} />
Google Fonts
Using CustomFont
is recommended for best performance. However, you can use
the GoogleFont
component instead if you prefer to use Google's CDN-hosted
fonts (note they are also available to download from
http://google-webfonts-helper.herokuapp.com).
In your Shop.js
, include the GoogleFont
component. Pass it a
primaryFont
and/or secondaryFonts
(as described under Common props
above).
Use the family string as provided by the Embed panel on Google Fonts. For
example, for Source Sans Pro with semi-bold and Vietnamese support, the
string is: Source+Sans+Pro:400,600&subset=vietnamese
<GoogleFont
primaryFont="Source+Sans+Pro:400,600&subset=vietnamese"
secondaryFonts={["Lato", "Roboto"]}
/>
The above will result in an html tag like this once the fonts have loaded:
<html class="source-sans-pro-ready lato-ready roboto-ready"></html>
For better performance, add the following preconnect hint
to the head of your index.html
:
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
Typekit
Typekit bundles files together and provides an id
for their embed code, as
described at https://helpx.adobe.com/fonts/using/embed-codes.html.
The TypekitFont
component is used in the same way as the above components,
but you must also provide the id.
<TypekitFont id="glm4yoq" secondaryFonts={["adobe-clean"]} />