How do I add google fonts to a gatsby site

Viewed 34089

Getting started with Gatsby - when I add a link tag to public/index.html with the google font it works in development mode. When I build the site the index.html gets reset. So I guess there is another proper way to add the font?

12 Answers

You can also use react-helmet, which is discussed in the gatsby tutorial.

Include a google fonts link element within the helmet component.

Like this:

<Helmet>
  <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"/>
</Helmet>

I ended up going down this route because I had already done some styling manually, and when I tried using Typography it made a bunch of changes that would have taken me a while to undo.

Add the following to the top of src/layouts/index.css for example to import the 'Roboto' font by Google

@import url('https://fonts.googleapis.com/css?family=Roboto');

html {
  font-family: 'Roboto', sans-serif;
}

This will then be handled by the gatsby build process and included in the final production version of the site.

I was under the impression Typefaces was the way to go. No extra (blocking) network requests.

As long as you can find your typeface- font on NPM

If you are using Material UI in combination with Gatsby, here is the optimal way:

Add the CDN href in combination with React Helmet as suggested in the Material UI documentation and the official Material UI Gatsby example from their github repository:

Create a file RootLayout.jsx (or name it however you want):

import React from "react";
import { Helmet } from "react-helmet";
import CssBaseline from "@material-ui/core/CssBaseline";

export default function RootLayout({ children }) {
  return (
    <>
      <Helmet>
        <meta
          name="viewport"
          content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
        />
        <link rel="stylesheet"
              href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600&display=swap" />
      </Helmet>
      {children}
    </>
  );
}

Add this code to your gatsby-browser.js:

export const wrapRootElement = ({ element }) => <RootLayout>{element}</RootLayout>;

Add the same code snippet to your gatsby-ssr.js:

export const wrapRootElement = ({ element }) => <RootLayout>{element}</RootLayout>;

Explanation

The code in the layout is wrapped around your React app using the Gatsby Browser and SSR API. This way the font is available throughout your whole Gatsby app.

Link to Gatsby Browser API

Link to Gatsby SSR API

You can also host the fonts by yourself. Just

In this example the src-folder shoud look like:

/src/
     /styles/style.scss
     /fonts/roboto-v18-latin-regular.eot
     /fonts/roboto-v18-latin-regular.woff2
     /fonts/roboto-v18-latin-regular.woff
     /fonts/roboto-v18-latin-regular.ttf
     /fonts/roboto-v18-latin-regular.svg

* you have to have a plugin like to use scss: https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-sass

According to Gatsby(react) Docs, gatsby-plugin-offline may prevent Google fonts from being requested on the server if they do not end in .css. I used Typography and ended up importing one font from CDN but later saw here this option to pass in gatsby-config to override the plugin's default.

@martis solution is great for older gatsby applications, but starting from gatsby@4.19.0 you can directly use the Gatsby Head API. As you'll see in the link, you would need to export a named Head function within your page:

export function Head() {
  return (
    <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"/>
  )
}

Existing answers require either a manual download of the font (in one case) or embed a <link> which will slow down your site, even if it's prefetched (or will optimise to appear quick, but potentially expose the user to a FOUC by swapping in the fonts once downloaded).

In 2022 an alternative way of doing this is to use fontsource, in which case gatsby downloads and incorporates only the required CSS at build-time, not at load time.

Note that in some lighthouse reports (e.g. for branch previews on gatsby cloud) this can appear to slow down site load as compared to a with a preload tag, however in production where a CDN is involved, self-serving that CSS is extremely quick.

Here's how I did it for octue's open-source homepage full source code here for two different fonts of varying weights.

yarn add @fontsource/open-sans
yarn add @fontsource/work-sans
/*
 * Preload our font CSS at build-time
 * You can do this
 *  - in a theme file (e.g. if using material-ui), or
 *  - in gatsby-browser.js, or
 *  - where the fonts are first used
 */
import '@fontsource/open-sans/400.css'
import '@fontsource/work-sans/300.css'
import '@fontsource/work-sans/400.css'
import '@fontsource/work-sans/500.css'
import '@fontsource/work-sans/500-italic.css'

// The following is not necessary - for example using with MUI only
// If you're using Material-UI or similar, you'll be able to use the font directly
import { createMuiTheme } from '@material-ui/core'

const themeOptions = {
  typography: {
    h1: {
      fontFamily: "'Work Sans', sans-serif",
      fontStyle: 'normal',
      fontSize: '5rem', // Converted from '80px',
      fontWeight: 400,
      lineHeight: '5.5rem', // Converted from '88px',
    },
    body1: {
      fontFamily: "'Open Sans', sans-serif",
      fontWeight: 300, // TODO consider whether to raise to 400 for better aliasing and visibility
      fontSize: '1.125rem', // Converted from 18px
      lineHeight: '1.625rem', // Converted from 26px
      letterSpacing: '0.01rem',
    },
  },
}

  export const theme = createMuiTheme(themeOptions)
Related