Having trouble importing Google Fonts using Styled Components and Next.js?

I encountered an issue while attempting to load Google Fonts. I came across a solution that suggests adding the following code snippet in _document.js to import it within a head tag:

import React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <link
            rel="preload"
            href="/fonts/noto-sans-v9-latin-regular.woff2"
            as="font"
            crossOrigin=""
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}
export default MyDocument;

However, this approach conflicted with the code required to enable Styled Components in Next.js:

import Document, { DocumentContext } from 'next/document';
import { ServerStyleSheet } from 'styled-components';

export default class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }
}

Therefore, my query is: how can I adjust my _document.js file to incorporate the styles from Google Fonts?

Additionally, here is the GlobalStyle I am utilizing which does not include the imported fonts:

import { createGlobalStyle } from '@xstyled/styled-components';

const GlobalStyle = createGlobalStyle`

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

* {
    margin: 0;
    padding: 0;
}

*,
*::before,
*::after {
    box-sizing: inherit;
}

html {
    box-sizing: border-box;
    font-size: 62.5%; 
    position: relative;
    background: grey;
}

body {
  font-family: 'Lato', sans-serif;
}
`;

const BasicLayout = ({ children }: { children: any }) => {
  return (
    <>
      <GlobalStyle />
      {children}
    </>
  );
};

export default BasicLayout;

Answer №1

Visit this webpage for more information:

https://nextjs.org/docs/advanced-features/custom-app

Familiarize yourself with the concept of custom _app.js and then proceed as outlined below:

To begin, craft a personalized _app.js for your application. (This file should be located in the root of your pages directory)

Subsequently, generate a _app.css within the same folder

Afterwards, import the css file into your _app.js

import "./_app.css";

In your _app.css file, include your chosen Google font using the following syntax:

@import url("https://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700&display=swap");

Within the css file and inside the body tag, incorporate the following line:

body {
  font-family: "PT Sans Narrow", sans-serif;
  etc..
}

Answer №2

Encountering the same issue led me to explore a different solution from Hooman's answer, which involved creating a standalone .css file solely for importing Google fonts.

Here is an alternative method for loading fonts while utilizing styled-components:

import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
  DocumentInitialProps,
} from "next/document";
import { ServerStyleSheet } from "styled-components";

class MyDocument extends Document {
  // Ensure styles are loaded before rendering
  static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html lang="en">
        <Head>
          {/* Google Fonts */}
          <link rel="preconnect" href="https://fonts.googleapis.com" />
          <link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
          <link
            href="https://fonts.googleapis.com/css2?family=Libre+Franklin:wght@400;500&display=swap"
            rel="stylesheet"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

Ensure that your render method is not marked as static.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting a maximum quantity in React

I'm struggling with limiting the number of items a user can add to their cart in a React function called handleNumberSum. I attempted using an if statement, but it doesn't seem to work as expected. Here's my code: const ItemCount = () => ...

Having trouble accessing the property of undefined in material ui cards

Currently, I am incorporating Material UI cards into my React project. One issue I encountered is trying to implement two functions, onMouseOver and onMouseOut, in my cards. However, when I run the code, I receive an error message stating "Uncaught TypeE ...

I could really use some assistance in resolving this useEffect problem

After adding data to the localhost using the app, I noticed that upon reloading the page, the data is lost. It seems like I may have misused the useEffect function in my code. Can someone please review the code and help me figure out what mistake I am ma ...

Only one multi-dependency useEffect call is triggered when new values are sequentially set

Monitoring for changes in 2 key variables, step and reviewElementId, my useEffect is designed to trigger when either of them are updated. useEffect(() => { //... }, [step, reviewElementId]); When a function called update is executed, it sequentiall ...

"Maximizing the Potential of refetchQueries in reason-apollo: A Comprehensive Guide

Encountering issues setting up refetchQueries with reason-apollo. Following a setup similar to the swapi example here, I have a listing and a form for adding new items via a mutation. Upon successful mutation, the goal is to refetch the items in the listin ...

jquery sequential fade effect

I am trying to make each div fade in one by one. Visit this link for reference <div id="w"> <div class="one"></div> <div class="two"></div> <div class="three"></div> </div> $(function() { $(&a ...

Conceal the MUI data table until the file has been uploaded

I need to ensure that the data table remains hidden until I upload my file. Currently, the table appears as blank but I want it to only be visible after the file is uploaded. var selectedList = {}; const columns = [ { name: "id", label: "Select", o ...

Encountering a CORS policy issue while attempting to retrieve data from an API

I have been attempting to retrieve data from the DHL API, however, I keep encountering issues due to CORS policy blocking the request. Even though I have configured the CORS policy on my backend server, the error persists. What could be the issue? Here ...

When utilizing Reactjs, accessing an element by its id becomes challenging when the element is nested within a map() function

Currently, I am encountering an issue related to reactjs. In my scenario, I have a requirement to compare the height of the screen with a specific div to determine its maximum width. The challenge lies in the fact that the particular div I need to analyz ...

React-native: Tried to redefine the property 'color'

My index.android.js file is giving me an error after navigating to login.js. How can I track down where this error is occurring? I've already run eslint, but it didn't detect any errors. /** * Sample React Native App * https://github.com/faceb ...

Could someone lend a hand in getting the X to align properly on this div? I've been struggling with it for ages and just can't seem to crack

This is a demonstration of the CodePen project: Click here to view <div class="annotation"> <div class="annotext"> <div class=annobar></div> <div class="x">✕</div> Lorem ipsum dolor sit amet, consectetur adipiscing e ...

When incorporating Redis into the getServerSideProps function, an error is thrown stating that net.isIP is not a valid

Is my understanding correct that getServerSideProps is used to pre-render data on each render? I am encountering an error when using the standard redis npm module in getServerSideProps - specifically, the error message "net.isIP is not a function". After r ...

What is the best way to shift all components on the screen when the keyboard is opened in a React Native app

In my setup, I have two components: one black and the other red. When I open the keyboard, only the red component moves upward while the black one remains stationary. This results in the red component stacking on top of the black one. How can I ensure tha ...

The element residing within the body exceeds the body's dimensions

HTML : <body> <header> <div> </div> </header> </body> CSS : body { width : 1000px ; } header { width : 100% ; } If these codes are implemented, The header's width should be the same as the body's ...

Is there a way to have the span update even if the input stays the same? Currently, it only changes when the input is different

Retrieve results of 3 lines (Ps) by entering a word in the text area and clicking search. If the word is found after clicking the button, a span will be displayed with the count of occurrences as well as the highlighted P(s) where it was found. If the wo ...

Having trouble with my OpenAI API key not functioning properly within my React application

I've been struggling to implement a chatbot feature into my react app, specifically with generating an LLM-powered response. Despite going through documentation and tutorials, I haven't been successful in resolving the issue. My attempts involve ...

Is it possible to access the CSS property from an external CSS file even when inline styles are used?

Is there a way to retrieve the css property from an external source using JavaScript or jQuery even if inline styles are applied to the same element? Here's an example: <div id="my" style='left:100px'>some content</div> <styl ...

Tips for adjusting the font size options within the Autocomplete feature of Material UI Version 5

Is there a way to adjust the font size of the drop-down items? I have tried various methods to change the font size, including: How do I change Material UI Autocomplete font size? How to change fontsize of options in Material ui autocomplete? Unfortuna ...

There are no HTTP methods being exported in this specific file. Remember to export a named export for each individual HTTP method

Currently, I am working on a React.js/Next.js project that incorporates Google reCAPTCHA. The frontend appears to be functioning properly as I have implemented print statements throughout the code. However, I am encountering an error in the backend display ...

Modifying the font style and color of text within the table header - Material Table version 0.19.4

Recently, I began using React and Material UI but have encountered an issue with modifying the color and font of text in the table header. Despite attempting to override it, the default style remains unchanged. It has been mentioned that utilizing "heade ...