Tutorial

How To Add Custom Fonts to Gatsby

GatsbyJS

Introduction

Choosing the right font can add great value to a site and enhance the user experience. The right font-loading strategy, however, can be somewhat of a challenge. That’s why Gatsby provides several developer-friendly solutions for all of your font-loading needs.

In this article, you will be introduced to three different approaches for loading fonts onto a project: Typography.js, Fontsource, and managing self-hosted files manually.

Prerequisites

If you would like to follow along with this article, you will need:

This tutorial was verified with Node v15.13.0, npm v7.8.0, gatsby v3.2.1, and react v17.0.1.

The Typography,js section was verified with gatsby-plugin-typography v3.2.0, react-typography v0.16.19, typography v0.16.19, and typography-theme-lawton v0.16.19. The Fontsource section was verified with @fontsource/rubik v4.2.2.

Using Typography.js

Typography.js is a toolkit for loading and configuring web fonts for your projects.

gatsby-plugin-typography will need to also include peer-dependencies of typography and react-typography.

Open your terminal window and navigate to your project directory and run the following command:

  • npm install typography react-typography gatsby-plugin-typography

Note: At the time of revision, there was a dependency tree conflict with the latest version of React, gatsby-plugin-typography, and react-typography.

It is possible to use the --legacy-peer-deps flag to get around this error.

Next, open the gatsby-config.js file with your code editor and add the following new lines of code:

gatsby-config.js
module.exports = {
  // ...
  plugins: [
    // ...
    {
      resolve: "gatsby-plugin-typography",
      options: {
        pathToConfigModule: "src/utils/typography.js"
      }
    }
  ]
};

gatsby-plugin-typography supports two options:

  • pathToConfigModule: this is the config path.
  • omitGoogleFont: a helper function to request Google fonts from standard CDN. If set to true, you can use an alternative CDN config.

Next, you will need a typography.js configuration file as specified in the pathToConfigModule option. This file is where you set web fonts or a theme, as well as any additional base styling.

Let’s add Playfair Display, Roboto, and some base font sizing.

src/utils/typography.js
import Typography from "typography";

const typography = new Typography({
  baseFontSize: "18px",
  baseLineHeight: 1.45,
  googleFonts: [
    {
      name: "Playfair Display",
      styles: ["800"],
    },
    {
      name: "Roboto",
      styles: ["400"]
    }
  ],
  headerFontFamily: ["Playfair Display", "serif"],
  bodyFontFamily: ["Roboto", "sans-serif"]
});

typography.injectStyles();

export default typography;

Save your changes and view the new fonts in your Gatsby project.

Note: If your starter includes styles, they may overwrite styles set by gatsby-plugin-typography.

Typography.js also supports pre-defined themes.

Consider an example with the Lawton theme which uses Raleway for headings and Libre Baskerville for body text.

Open your terminal window and run the following command:

  • npm install typography-theme-lawton

Here is an example of using a pre-defined theme:

src/utils/typography.js
import Typography from "typography";
import theme from "typography-theme-lawton";

const typography = new Typography(theme);

export default typography;

Here is an example of overriding a pre-defined theme with overrideThemeStyles:

src/utils/typography.js
import Typography from "typography";
import theme from "typography-theme-lawton";

theme.overrideThemeStyles = () => ({
  a: {
    color: "black",
    textDecoration: "none",
    borderBottom: "2px solid gold"
  },

  "a:hover": {
    color: "black",
    textDecoration: "none",
    borderBottom: "2px solid gold"
  }
});

const typography = new Typography(theme);

export default typography;

There are plenty of themes you can use and several configuration options to get the right setup for your site.

Now your Gatsby project supports Typography.js.

Using Fontsource

Fontsource is a toolkit for self-hosted Open Source fonts. Self-hosting has a typical advantage of faster loading times compared to CDN-hosted fonts.

Note: Previously, this article recommended Typefaces. This library has since been deprecated.

Consider an example with the Rubik font.

Open your terminal window and run the following command:

  • npm install @fontsource/rubik

Next, require the font in the gatsby-browser.js file, where you interact with the client-side of Gatsby.

gatsby-browser.js
require("@fontsource/rubik");

And then you can call the font in your stylesheet:

src/styles/main.css
body {
  font: 400 18px Rubik, sans-serif;
}

Note: Using a global style will require you to add an import line to gatsby-browser.js:

gatsby-browser.js
import "./src/styles/main.css"

Or styled-components:

src/components/layout.js
import { createGlobalStyle } from 'styled-components';

const GlobalStyles = createGlobalStyle`
  body {
    font: 400 18px Rubik, sans-serif;
  }
`

const Layout = ({ children, location }) => (
  // ...
  <GlobalStyles />
  <Main>{children}</Main>
  // ...
);

export default Layout;

Now your Gatsby project supports Fontsource.

Managing Self-Hosted Files Manually

Fontsource is a self-hosting solution and provides the files you need. However, there may be situations where you want finer control over the setup. Maybe you want to take more advantage of the CSS Font Loading API. Or even try out some of the font loading strategies from Zach Leatherman. Whichever the case may be, you can always add fonts to a Gatsby site like you normally would with any website.

Keeping with the previous Rubik example, you can create a directory for your font files and stylesheet:

|-- /static
    |-- /fonts
        |-- Rubik-Regular.woff
        |-- Rubik-Regular.woff2
        |-- Rubik-Italic.woff
        |-- Rubik-Italic.woff2
        |-- Rubik-Bold.woff
        |-- Rubik-Bold.woff2
        |-- fonts.css

You can then source the directory with the help of the gatsby-source-filesystem plugin:

gatsby-config.js
module.exports = {
  // ...
  plugins: [
    // ...
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "fonts",
        path: `${__dirname}/static/fonts/`
      }
    }
  ]
};

And in your stylesheet, you can use the @font-face rule to load the fonts:

src/fonts/fonts.css
@font-face {
  font-family: Rubik;
  font-weight: 400;
  font-style: normal;
  src: url("Rubik.woff2") format("woff2"), url("Rubik.woff") format("woff");
  font-display: swap;
}

@font-face {
  font-family: Rubik;
  font-weight: 400;
  font-style: italic;
  src: url("Rubik-Italic.woff2") format("woff2"), url("Rubik-Italic.woff") format("woff");
  font-display: swap;
}

@font-face {
  font-family: Rubik;
  font-weight: 700;
  font-style: normal;
  src: url("Rubik-Bold.woff2") format("woff2"), url("Rubik-Bold.woff") format("woff");
  font-display: swap;
}

And now you can call your fonts in the same way you did in the previous Fontsource example - via a stylesheet or styled-component.

Conclusion

In this article, you were introduced to three different approaches for loading fonts onto a project: Typography.js, Fontsource, and managing self-hosted files manually.

Finding the right solution for your needs can significantly improve performance and user experience.

Continue your learning with How To Deploy a Gatsby Application to DigitalOcean App Platform.

Creative Commons License