Utilizing global styles for fonts across Next.js version 13

As I transition a create-react-app to nextjs, I'm navigating the new features and challenges. Nextjs 13 brings in next/font, which seems like a valuable addition as I venture into Next.js for the first time. It makes sense to incorporate it into my workflow rather than relying on deprecated methods.

Motivation

My goal is to utilize multiple Google Fonts and have the ability to dynamically apply them throughout the app. I envision creating a central file:

fonts.js

import { Roboto, Poppins } from '@next/font/google';

export const roboto = Roboto({
    weight: '400',
    subsets: ['latin'],
    variable: '--roboto-default'
});
export const poppins = Poppins({
    weight: '400',
    subsets: ['latin'],
    variable: '--poppins-default'
});

This setup would allow me to reference these fonts in any component, ensuring that any changes made will be reflected across all affected components.

Past Experiences / Familiarity

In react-create-app, I utilized sass globals in external stylesheets. By following the standard @import method in a stylesheet and declaring a variable like so:

globalfonts.sass

$font01: 'Roboto, arial, sans-serif';

Components could reference this global font variable in their individual stylesheets:

import globalfonts.sass
.componentname {
   font-family: $font01
}

By modifying the value of $font01, all components would automatically update, making it easier to experiment with design changes. Additional variables like $font01--size could also be implemented for further customization.

Question

I am seeking a similar functionality in nextjs13 using next/font within a stylesheet, akin to my previous experiences detailed above, rather than utilizing inline references in each component. While I have set up an app/fonts.js file, importing it into app/layout.js, I am uncertain about the next steps given the shift away from the pages directory structure.

While I can import constants from fonts.js into each component and reference them inline, blending styles between stylesheets and inline references complicates the process. Leveraging sass globals for quick, universal font configuration adjustments seems more intuitive.

Follow up question:

Considering the lack of emphasis on stylesheets in discussions related to next/font online, I raise the question: Are stylesheets becoming obsolete? Is the trend shifting towards styling components individually on a case-by-case basis?

Attempt

If I implement the following in app/layout.jsx

import { roboto, poppins } from './fonts';
import styles from './globals.scss'

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            {/*
                <head /> will contain the components returned by the nearest parent
                head.jsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
            */}
            <head />
            <body className={roboto.className}>{children}</body>
        </html>
    )
}

The roboto font is not applied, leaving me unsure of my mistake.

If resorting to using className={roboto.className} on every single component where the font should be used (as some suggest), it may complicate future font changes without a centralized reference point like my old approach with $font01.

Answer №1

After diving into the world of NextJS 13, I have discovered a nifty solution for incorporating Next/Font and applying it dynamically across your application via a stylesheet. Leveraging the same Font.js file as mentioned previously has proven to be quite effective.

Within the '_app.s' file:

import Layout from '@/components/layouts/Layout';
import { roboto, poppins } from '@/utils/fonts';
import '@/styles/globals.scss';

export default function App({ Component, pageProps }) {
  return (
    <div className={`${roboto.variable} ${poppins.variable}`}>
      <Layout>
        <Component {...pageProps} />
      </Layout>
    </div>
  );
}

In the 'global.scss' file:

$primaryFont: var(--poppins-default);
$headingFont: var(--roboto-default);

p {
  font-family: $primaryFont;
}

h1 {
  font-family: $headingFont;
}

You also have the option to utilize CSS variables directly to define the font in any class or element, but utilizing Sass to designate a variable for styling entire groups of elements like demonstrated above is standard practice. Additionally, if you ever decide to switch fonts, simply modifying the reference to the CSS variable will seamlessly apply the change throughout.

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

Ways to calculate the total sum of values in an array of objects using MongoDB techniques

i have a document in my MongoDB collection that has the following structure: [ { "_id": { "$oid": "64a5a396ec152ab4f5e1c60c" }, "firstName": "Ram", "lastName": "Shayam ...

How to prevent the toolbar from overlapping with the background image in a reactjs

Hey there, I'm looking to create a toolbar with an image in the background. To achieve this, I've created two separate components. First up is the image component: import React from 'react'; import thepic from '../mypic.jpg'; ...

Having trouble uploading my React application onto Google App Engine

Here is the error that keeps popping up when I attempt to deploy my newly launched React app (it works perfectly fine on my local machine). Below is a snippet of my app.yaml configuration file. runtime: nodejs env: flex manual_scaling: instances: 1 reso ...

Folding at the start of sentences within a paragraph tag

Utilizing TinyMCE for my users to generate their own web pages is my current project. My main objective is to ensure that whatever content users type into the editor appears exactly as it does when published on the page. I am close to achieving this, howev ...

Avoid having the browser automatically move focused elements that are navigated to using the tab key

When moving through form elements or anchors using the tab key (and shift + tab), the browser automatically scrolls to the focused element. If the element is not visible due to being part of overflow content with a hidden overflow setting, the container&ap ...

Having Trouble Setting Default Value in React Typescript MUI Autocomplete

I am encountering an issue with my React and Typescript code using MUI with the use of hook form. The problem arises when trying to set a default value for an Autocomplete field, resulting in the following error message: I am seeking assistance in resolvi ...

What is the best way to position a title and subheading alongside an image?

I am currently working on developing a blog using php and html to enhance my coding skills. On my website, I have a special category where I display posts, the number of which can vary. Each post is composed of a title, a subheading, and a placeholder div ...

When the caret triangle is upside down, it indicates that a drop-down menu is available even when the

I am facing an issue with a dropdown list where the triangle indicator is incorrectly displayed: https://i.stack.imgur.com/L4NBW.png Both images show that the arrows are in reverse direction, and I am struggling to identify the cause of this problem. He ...

Fading CSS Background Transition with Responsive Design

One generous member of our online community shared a CSS rollover code that is "fluid" and can adapt to different browser sizes. The code is provided below, along with a link to JsFiddle: CSS .container { width: 100%; height: 300px; backgroun ...

What is the best way to prevent an iFrame from causing its parent window to scroll?

I recently came across an HTML document that includes an iframe towards the bottom of its content. Specifically, the iframe is embedding a Google Spreadsheet, using the following code: <iframe id="gsheet-group" width="100%" height=& ...

Definition of JSON Schema attribute: Field schema not supported for field... : Type of field is undefined

I am in the process of creating a form that is based on a JSON schema and utilizing the react-jsonschema-form component for ReactJS. The purpose of this form is to allow users to input various settings (such as CSS/HTML selectors) that will be used to ext ...

The input elements fail to register the passed-in value until they are clicked on

I am experiencing an issue with my form element that contains a few input fields. Two of these inputs are set to readOnly and have values passed in from a calendar element. Even though the input elements contain valid dates, they still display an error mes ...

Error encountered: Unable to access undefined properties while attempting to make an API call to AirTable using NextJS version 13.4

Currently in the process of learning how to use the App router with NextJS 13.4, I encountered an issue while attempting to make an external API call. Even though I am getting all the data correctly from Airtable, Next throws an error that disrupts my try ...

What steps should I take to fix the error I'm encountering with React Material UI

import { AppBar, Toolbar, Typography } from '@material-ui/core' import React from 'react' import { makeStyles } from '@material-ui/styles'; const drawerWidth = 240; const useStyles = makeStyles((theme) => { return { ...

Discovering the RGB color of a pixel while hovering the mouse in MapboxGL Js

Looking to retrieve the RGB color value of the pixel under the mouse hover in MapboxGL Js. What is the most effective method to accomplish this task? ...

Easiest method to change cursor to 'wait' and then return all elements to their original state

On my website, there are certain CSS classes that define a specific cursor style when hovered over. I am trying to implement a feature where the cursor changes to a "wait" image whenever an AJAX call is initiated on any part of the page, and then reverts b ...

What is the method for setting a variable to an object property's value?

I am currently working on a React app and I have an object structured like this: state = { property1: 'value', property2: 'value', property3: 'value', property4: 'value', } I am trying to write a fu ...

Stop listening to Firestore changes from another function in React.js

Is there a way to stop listening to Firestore onSnapshot from a different function? Although I can retrieve data from Firebase, I am unable to access the unsubscribe() function. How can I resolve this issue? let unsucscribe; useEffect(() => { ...

What is the best way to iterate over my JSON data using JavaScript in order to dynamically generate cards on my HTML page?

var data = [ { "name":"john", "description":"im 22", "email":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4c7d7e7f0c2b212d2520622f">[email protected]</a>" }, { "name":"jessie", ...

Guide to adjusting column size across various screen resolutions using Vuetify grid

For my Vue and Vuetify dashboard, I have opted to use the grid system in Vuetify's library to structure the layout. However, I am encountering an issue where the appearance varies depending on the screen resolution. Is there a way to keep the left con ...