using google fonts in nextjs with sass, css and semantic ui react

14,836

Solution 1

I know in Next.js 9.3, you can copy the @import statement from Google Fonts:

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

and place this in some css file, lets say styles/fonts.css like so:

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

.jost {
  font-family: 'Jost', sans-serif;
}

Then import that inside of your global _app.js file like so:

import `../styles/fonts.css`

Now you have global access to that class containing the Google Font in every next.js page

Solution 2

I think the other solution is to use fonts directly from Google. Just customize _app.js file and add a <link rel="stylesheet" /> in the <Head />

Example _app.js

import React from 'react';
import App, { Container } from 'next/app';
import Head from 'next/head';

export default class MyApp extends App {
  static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    return { pageProps };
  }

  render() {
    const { Component, pageProps } = this.props;

    return (
      <Container>
        <Head>
          <link
            href="https://fonts.googleapis.com/css?family=Cabin"
            rel="stylesheet"
            key="google-font-cabin"
          />
        </Head>

        <Component {...pageProps} />

        <style global jsx>{`
          body {
            font-family: 'Cabin', sans-serif;
          }
        `}</style>
      </Container>
    );
  }
}

Solution 3

 class NextApp extends App {
  render() {
    const { Component } = this.props
    return (
          <React.Fragment>
            <Component {...pageProps} />

            <style jsx="true" global>{`

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

              body {
                margin: 0;
                font-family: 'Roboto', sans-serif;
              }

            `}</style>

          </React.Fragment>
        </Provider>
      </Container>
    )
  }
}

Including the font url from Google Fonts in styled-jsx worked for me.

Solution 4

As per the latest docs you can now add global css by updating the _app.js file and importing your css style. Follow the steps below

  1. Create custom _app.js file in the pages directory by following the docs.
  2. Add your styles.css file to the pages directory.
  3. Include the styles as below

// _app.js

// Import styles
import './styles.css'

// Function to create custom app
function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

// Export app
export default MyApp

and done. These styles styles.css will apply to all pages and components in your application. Due to the global nature of stylesheets, and to avoid conflicts, you may only import them inside _app.js.

Share:
14,836
Shaun Chua
Author by

Shaun Chua

Updated on June 09, 2022

Comments

  • Shaun Chua
    Shaun Chua almost 2 years

    I have a next.config.js file that has the following configuration:

    const withSass = require('@zeit/next-sass');
    const withCss = require('@zeit/next-css');
    
    module.exports = withSass(withCss({
      webpack (config) {
        config.module.rules.push({
          test: /\.(png|svg|eot|otf|ttf|woff|woff2)$/,
          use: {
            loader: 'url-loader',
            options: {
              limit: 100000,
              publicPath: './',
              outputPath: 'static/',
              name: '[name].[ext]'
            }
          }
        })
    
        return config
      }
    }));
    

    This is great because it runs my semantic ui css files.

    Now I have a problem. I can't seem to successfully import any google font url. I tried downloading the ttf file into my file path and tried to reference it with the @import scss function. However I get a GET http://localhost:3000/fonts/Cabin/Cabin-Regular.ttf net::ERR_ABORTED 404 (Not Found) error

    Here is what I'm trying to do with google font:

    @font-face {
      font-family: 'Cabin';
      src: url('/fonts/Cabin/Cabin-Regular.ttf')  format('truetype');
    }
    
    $font-size: 100px;
    .example {
      font-size: $font-size;
      font-family: 'Cabin', sans-serif;
    }
    

    I have also downloaded the relevant npm dependencies:

    "@zeit/next-css": "^1.0.1",
    "@zeit/next-sass": "^1.0.1",
    "file-loader": "^2.0.0",
    "next": "^7.0.2",
    "node-sass": "^4.9.4",
    "react": "^16.6.0",
    "react-dom": "^16.6.0",
    "semantic-ui-css": "^2.4.1",
    "semantic-ui-react": "^0.83.0",
    "url-loader": "^1.1.2"
    
  • Shaun Chua
    Shaun Chua over 5 years
    what would you consider as best practice? housing the font in local folders or what you just suggested?
  • iurii
    iurii over 5 years
    I would go with the approach when I use fonts from Google via API instead of downloading them locally. Some benefits I see: 1. If I need to add more fonts from google I dont need to download anything just add a font name to the URL and that's it 2. No need to tweak next.js webpack config to load fonts
  • schabluk
    schabluk over 5 years
    That works great. I would put it to _document.js though.
  • rhysclay
    rhysclay about 5 years
    I would consider a local copy best practice - along with the css font display setting you can avoid an unecessary network request
  • Indika K
    Indika K about 3 years
    I would consider this as the best practice.