Typography can make your applications :sparkles: zing :sparkles:!!!
Adding Google Fonts allows you to use custom fonts in your apps. They are advertised as free and there are over 900+ font families to choose from. Since 2018, Google has recommended self-hosting as a way to add their fonts.
There are number of web safe fonts, that are free and built into various platforms. However, sometimes we need something that is more customised, to serve our design purposes.
So "without much further-a-do"...
This repo
specifically targets the self-hosting of Google Fonts, rather than using a link to their CDN, and how to integrate them into a Next.js app that uses Tailwind CSS.
There are number of pros and cons for self-hosting, which have been discussed in many articles and blogs, I wont be detailing these here. I have provided a few links at the end of this readme file, for further reading.
Google Fonts are advertised as Open Source and free to use...
But Don't take my word for it, (I'm no laywer and this is not legal advice)
All fonts used in this example are sourced from Google Fonts under the SIL Open Font License (OFL) V1.1. I have taken care to incorporate the licenses into the self-hosting folders within the repo, which is requested in the OFL.
:bulb: Note: you should always read the font license information yourself since you're responsible for following it. At this time Google Fonts use OFL v1.1, some use the Apache 2 license. The Ubuntu fonts use the Ubuntu Font License v1.0
You should seek legal advice before self-hosting or using any Custom Fonts.
You can get hold of Google Fonts in a number of ways, (this is not an exhausitive list), using the following tools:
Fonts can also be found on Googles Github Repo.
Once, you have downloaded them you can add them to your project to self-host.
The easiest way to host them is under a public
folder, in a sub folder named fonts
.
I've structured the font resource locations as follows, you dont have to follow this, it demonstrates flexibility and that all fonts can be organised rather than just being placed under the
fonts
sub folder.
├── public
| └── fonts
| └── google
│ ├── font(s) by name
│ │ │ ├── .woff / .ttf (etc)
│ │ │ ├── .css
│ │ │ ├── licence.txt
├── styles
| └── global.css (app-base.css)
├── .gitignore
├── jsconfig.json
├── postcss.config.js
├── tailwind.config.js
The fonts will be serverd from this location to our Next.js app.
Once we have downloaded the font files, licenses, stylesheets etc and structured the folders, we need to perform font loading.
We can use @font-face to load the fonts. See the CSS files placed alongside the font resources in the font
folder above.
We can eventually import these into the Tailwind styles CSS file. Normally this is called global.css
, I'm using 3 files which are imported into the Next.js _app.js file.
For example:
@font-face {
font-family: 'Oswald Variable'; /*Ive added a prefix to let me know its a variable font*/
font-style: normal;
font-weight: 200 700;
src: local('Oswald'),
url(/fonts/google/oswald/Oswald-VariableFont_wght.ttf) format('truetype');
font-display: swap;
}
We next perform some small optimisations for the font(s) loading using the font-display
attribute.
By using @font-face
in combination with font-display
attributes we can prevent FOUT and FOIT.
There are a number of strategies available to implement this:
Strategy | Description |
---|---|
1. block |
dont render anything to the user until the fonts loaded. |
2. swap |
recommended for google fonts. it will swap out once the font loads. |
3. fallback |
not recommended. It still shows invisible text like block for a short time, but will eventually fallback to a safe font. |
4. optional |
a good choice when font is not important, more focus on brand and content. Is like slow connected fallback that might not even load a font. |
This is a new rule you can add to your font-face declaration that tells the browser to use the fallback system safe-fonts you have listed (e.g. Sans Serif), then swap to the desired font when it has been downloaded.
Its a good performance improvement as it displays content without waiting for downloads to finish.
font-display: swap;
does have the drawback of flashing this unstyled text if the font has yet to load. But we can remedy that with Preload.
We can preload our fonts in the <head>
of our page app. This is especially useful for those critical bits of typography that we want to display without flashing.
Todo this, we can add <preload>
to the head of our page(s).
In Next.js we add it into the custom _document.js
as follows:
<Head>
<link
rel="preload"
href="/fonts/google/grandstander/Grandstander-VariableFont_wght.ttf"
as="font"
type="font/ttf"
crossOrigin="anonymous"
/>
</Head>
:bulb: Note: be careful when using Preload, as it can have a negative effect, if overused. So we use it wisely. Its a way of setting the importance of a resource, we can also do the same for our script
resources if needs be.
Next we create a Fonts.css
file under the public\fonts
folder. This is where we import the various CCS files for the Google Font resources loaded using @font-face
above, i.e.
@import './google/oswald/Oswald-Variable.css';
This is then imported into the tailwind style file below.
Next we add the following to the app-base.css
file under the ./styles
folder.
We use the @layer
directive to tell Tailwind which "bucket" we are adding the font styles too.
Valid layer directives are a base, components, and utilities.
For example:
@layer base {
@import "../public/fonts/fonts.css";
}
We then import the styles to the _app.js
file:
import '@/styles/app-base.css';
import '@/styles/app-components.css';
import '@/styles/app-utilities.css';
Finally, we set up the tailwind.config.js
file to add the font familes to our app.
We either add them to the base font themes or extend the themes (or both).
For example:
const { fontFamily } = require('tailwindcss/defaultTheme');
module.exports = {
fontFamily: {
sans: ['Oswald Variable, Arial', fontFamily.serif],
serif: ['Merriweather Sans, Georgia', fontFamily.serif],
},
extend: {
fontFamily: {
'Grandstander-VariableFont': ['Grandstander Variable'],
},
},
},
;
That's it. We are done, see the code for more detail.
Thanks for reading. :smile: :thumbsup:
:star: :star: :star: Please star me, if you found this useful. :star: :star: :star:
Here follows, :books: more information :books: for those that may find it useful. :point_down:
Remember you can use lighthouse to test the performance of your page, this will also look for Font and Scripts optimsations and include recommendations, including FOUT and FOIT issues.
Once built I'm pleased to say this demo gets the following when running locally.
The main reasons I choose to self host, are as follows:
1. Google recommends it | Its now recommended by Google themselves. Since 2018, Google has recommended self hosting, for optimal peformance through preloading. Self-hosting is free and is encouraged, see this video: Google Chrome Developers: Web Performance made easy. |
2. better for privacy | 3rd party CDN's can use cookies and tracking algorithms you dont neccessarily know about. This can be a problem in countries where you need user consent, (i.e. Data Privacy and GDPR, see: GDPR-compliance of Google Fonts. |
3. better for security | more control on your own server). You actually call at least 2 domains when using the CDN. |
4. faster and more peformant | Google Fonts add resources that you may not need. You can choose font styles, etc and bundle and minify your own font-related CSS rules/files, giving fewer http requests. You can do this by ownly serving the specific fonts and unicodes you need for your sites typography. Specifiying parts of font familes rather than whole families. You can choose font styles, etc and bundle and minify your own font-related CSS rules/files, giving fewer http requests. |
5.offline availability | for mobile and desktop apps that are accessed offline. |
Try this out for yourself.
I would encourage you to test with your specific site/app and use the dev tools combined with "disable cache" and the built-in ability to change connection speeds.
I have not covered the use of npm packages
to add fonts. There are a number of flavours available online if this is your preference.
Some alternatives are to try using Fontsource, or next-google-fonts.