enginedave
enginedave

Reputation: 1003

How do I add google fonts to a gatsby site

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?

Upvotes: 48

Views: 35964

Answers (12)

Will Ayd
Will Ayd

Reputation: 7164

@martis solution is great for older gatsby applications, but starting from [email protected] 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"/>
  )
}

Upvotes: 1

thclark
thclark

Reputation: 5481

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)

Upvotes: 1

Daniel
Daniel

Reputation: 73

You can now just npm install the google font prefetch package and add any fonts you like to your gatsby-config file. Then use the font as you normally would in your css file. Checkout the gatsby docs here: https://www.gatsbyjs.com/plugins/gatsby-plugin-prefetch-google-fonts/

Upvotes: 1

EliteRaceElephant
EliteRaceElephant

Reputation: 8162

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

Upvotes: 6

martis
martis

Reputation: 820

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.

Upvotes: 52

lorio
lorio

Reputation: 49

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.

Upvotes: 2

Saša Šijak
Saša Šijak

Reputation: 9311

You can prefetch fonts with this plugin https://github.com/escaladesports/gatsby-plugin-prefetch-google-fonts This way in the build phase, the plugin will fetch your fonts and store it locally so you can serve them from your server or CDN.

Upvotes: 4

eurotrash
eurotrash

Reputation: 61

You can use the official google fonts plugin: https://www.npmjs.com/package/gatsby-plugin-google-fonts

Upvotes: 0

natterstefan
natterstefan

Reputation: 443

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

Upvotes: 2

skube
skube

Reputation: 6175

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

Upvotes: 10

Dade
Dade

Reputation: 241

You can also use typography.js like they reference in the docs:

https://www.gatsbyjs.org/tutorial/part-two/#typographyjs

Here is the typeography.js github page that lists all the font combination they currently have available.

Upvotes: 2

enginedave
enginedave

Reputation: 1003

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.

Upvotes: 47

Related Questions