Adding Google Fonts to Your Next.js App

Johnny AM

Overview

Typography can make your application come to life. Adding Google fonts (or custom fonts) to your Next.js project takes a few simple steps. This tutorial is written with Next.js 9.4

I wrote a short explanation of Web Fonts here that provides additional helpful details.

When possible, I opt to use hosted Google fonts, as they are quick to get going. However, the information here will allow you to self-host as well.

Create an empty Next.js project

Let's create a standard Next.js project and accept the default starter app.


> yarn create next-app
  

Use a Link Tag (Option 1 - my current preference)

Here we'll use the Google Hosted with Link tag method.

Next.js has an advanced feature called a Custom Document that allows you to augment your overall HTML document. In this case, we are looking to add a link tag to download the hosted google font in the document head.

Create a new file at pages/_document.js and add the contents


import Document, { Html, Head, Main, NextScript } from 'next/document'

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    return { ...initialProps }
  }

  render() {
    return (
      <Html>
        <Head>
          <link href="https://fonts.googleapis.com/css2?family=Lobster&display=swap" rel="stylesheet" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument
  

You'll notice the Lobster font type referenced in the Link tag. I used Lobster because it's different from the default Next.js font and fallbacks: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;

Use the font you prefer by visiting Google Fonts and grabbing the corresponding <link> tag.

Now, update the default css font-family rule in pages/index.js. You'll find this at the bottom of the index page. Replace the <style jsx global> tag with:


<style jsx global>{`
  html,
  body {
    padding: 0;
    margin: 0;
    font-family: Lobster;
  }

  * {
    box-sizing: border-box;
  }
`}</style>
  

Run your project with yarn dev. You should see the before and after screenshot of the font change. You'll notice the font on the right is now Lobster.


If you're on a Windows PC or Android, you may see a different default font (left side) here (I'm on macOS)

Use an @import CSS Rule (Option 2)

Your second option is to use a CSS @import rule to reference the Gooogle hosted font. You'll want to do this before any of your CSS classes reference the font. You can add this to the <style jsx global> tag that comes with the default Next.js project, but I prefer the flexibility of adding my own CSS class.

To add a CSS class, you need to add a custom _app component (learn more about custom apps). Add a new page called _app.js in the root of your project (pages/_app.js) with the content


import '../css/main.css'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp
  

Next, you'll create a new directory called css in the root of your project, and a file named main.css in that directory (css/main.css)


@import url('https://fonts.googleapis.com/css2?family=Lobster&display=swap');

/* can now reference my font */
body {
  font-family: Lobster;
}

/* my custom css */
  

Host your fonts locally

You'll need to define your own @font-face CSS rule if you purchased fonts or prefer to host them locally. The @font-face CSS rule contains the attributes that define your font.

You can read more about Web Fonts or the @font-face CSS rule.

In Next.js, you can add your fonts to the public directory. I recommend creating a public/fonts. You would then reference your fonts location in your @font-face like this.

In Next.js, you can add your fonts to the public directory. I recommend creating a public/fonts directory to store them. The @font-face CSS rule can then reference your font location like this.


/* this is an abbreviated version of @font-face, meant to show how to reference the font in the relative url attribute.
/* assuming the fonts were stored in public/fonts */

@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local('Roboto'), url(/fonts/roboto.woff2) format('woff2');
}
  

Common Questions / Answers

Why not use the next-google-fonts package to add fonts?

The next-google-fonts NPM package is great solution. My goal was to unpack how Google fonts and Next.js work together in case you prefer not to use an NPM package. Furthermore, if you have a custom font or prefer to host the Google font locally, the NPM package won't work in that scenario.

An advantage of using the NPM package is the optimization techniques included for faster loading and better lighthouse scores.

How performant is this approach? How do I increase my lighthouse score?

I have not shown many of the optiimization techniques to help with faster font loading. I can evolve this article if the demand is there. Ultimately YMMV with each approach. There are lots of conflicting reports and tests on which techniques are best practices and have the most positive impact.

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.

Terms of Service  |  Privacy Policy

© 2020 johnny.am. All rights reserved.