Custom Fonts in Gatsby

Juan Villela

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 our font-loading needs.

We’ll take a look at 3 different approaches for loading fonts onto a project. To get started, you’ll need a working Gatsby project. So if you haven’t already, you can get started with Gatsby by following along the Gatsby First Steps article.

Typography.js

Most of us have probably used Google Fonts for its ease of use and wide range of available typefaces. Typography.js turns that up to 11 and provides a wide range of typographic themes.

Install

All we need to install is the typography package.

$ npm install --save typography

Configuration

Then, we can add the plugin to our gatsby-config.js.

gatsby-config.js

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

Options:

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

Next, we need to set up a typography.js configuration file where we’ll choose our web fonts or 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,
  headerFontFamily: ["Playfair Display", "serif"],
  bodyFontFamily: ["Roboto", "sans-serif"]
});

// Insert styles directly into the <head>
typography.injectStyles();

export default typography;

Or, we could use one of the predefined themes.

src/utils/typography.js

import Typography from "typography";
import theme from "typography-theme-lawton";

const typography = new Typography(theme);

export default typography;

And we can even override any of the theme’s styles.

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;

Further Configuration

There are plenty of themes you can use and several configuration options to get the right setup for your site. Take a look at the linked resources to get a more in-depth look at what you can do with Typography.js.

Typefaces.js

Loading fonts from an external CDN comes with some drawbacks in performance, so if we’re looking to shed some of the extra load time, we can use Typefaces. This plugin takes a more familiar approach.

Install

Say we want to use Rubik for our site. Instead of adding a link in the head or an import in a stylesheet, we can npm install/yarn add the font we need.

$ npm install typeface-rubik

Configuration

Now we’ll require the font in our gatsby-browser.js, where we interact with the client-side of Gatsby.

gatsby-browser.js

require("typeface-rubik");

And we can go ahead and call the font in our stylesheet/styled-components like we normally would.

src/styles/main.css

body {
  font: 400 18px Rubik, sans-serif;
}

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;

Self-Hosted

Although using Typefaces is self-hosting our fonts, it does not provide us with much control over our setup. Maybe we want to take some 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, we can always add fonts to a Gatsby site like we normally would with any website.

Install

Keeping with the Rubik example, we can create a directory for our font files and stylesheet.

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

Configuration

We 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}/src/fonts/`
      }
    }
  ]
};

And in our stylesheet, we can use the @font-face rule to load our 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 we can call our fonts in the same way we did in the Typefaces example via a stylesheet or styled-component.

Conclusion

There are a plethora of different ways we could optimize our font-loading strategy, but this should be enough to get you started. I highly recommend you read through the linked resources and do a little research into some of the font-loading best practices. Finding the right solution for your needs can significantly improve performance and user experience.

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#