Exploring Next.js Font Styling and Utilizing CSS Variables

I'm attempting to implement the "next" method for adding fonts, but I find the process described quite complex just to preload a font.

I experimented with exporting a function to create the font and then using a variable tag to generate a CSS variable. However, this approach was unsuccessful even after importing the font into my page.js file. I exported a constant function to create the font with the variable:

import { Oxygen } from "next/font/google";

export const oxygen = Oxygen({
    display: 'swap',
    variable: '--font-oxygen',
    subsets: ['latin'],
})

Subsequently, I attempted to apply it in the linked CSS style sheet by setting the font family to the precise variable like so:

font-family: var(--font-oxygen);

My exploration of Nextjs is becoming discouraging due to this issue. The font doesn't seem to load properly, and I am hesitant to assign the class name of my HTML attributes to the font's class name unless I am misunderstanding something.

Answer №1

Make sure to utilize the font's font.variable approach instead of the font.className method.

import { Oxygen } from 'next/font/google'
 
const oxygen = Oxygen({ 
    display: 'swap',
    variable: '--font-oxygen',
    subsets: ['latin'],
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={oxygen.variable}> // USE .variable, NOT .className
      <Component {...pageProps} />
    </main>
  )
}

You can now apply that variable to any css class:

.text {
  font-family: var(--font-oxygen);
}

Please Note: While this is effective with app router, its compatibility with page router remains uncertain.

This technique should also pre-load the font, preventing flickering during page loading.

Answer №2

If you want to use a specific font throughout your entire application, you can easily import it in the index.js file (if using Pages Router) or in the layout.js file located in your app folder (if using App Router). There is no need to manually add it to your CSS.

Simply include classname={oxygen.className}

Here's an example for using Pages Router:

import { Oxygen } from 'next/font/google'
 
const oxygen = Oxygen({ 
    display: 'swap',
    variable: '--font-oxygen',
    subsets: ['latin'],
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={oxygen.className}>
      <Component {...pageProps} />
    </main>
  )
}

Answer №3

The information provided on this topic is quite lacking, but here is a solution I have come up with for loading multiple fonts:

Within the layout.tsx file of a project using an App Router:

import { customFont1, customFont2, customFont3} from "styles/customFonts";

const customFonts = [customFont1, customFont2, customFont3];
const customFontsClassName = customFonts.map((font) => font.variable).join(" ");

export default function MainLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body className={customFontsClassName}>
        <ThemeProvider> // if using a theme provider
          <GlobalStyles>
            {children}
          </GlobalStyles>
        </ThemeProvider>
      </body>
    </html>
  );
}

The font styles in styles/customFonts would look something like this:

const customFont1 = MyCustomFont1({ 
    display: 'swap',
    variable: '--font-custom1',
})
const customFont2 = MyCustomFont2({ 
    display: 'swap',
    variable: '--font-custom2',
})
const customFont3 = MyCustomFont3({ 
    display: 'swap',
    variable: '--font-custom3',
})

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

Using JavaScript to disable and re-enable an ASP.NET Timer control

I currently have a webpage built with ASP.Net that includes an ASP:Timer control <asp:Timer ID="TimerRefresh" runat="server" Interval="5000" Enabled="true" OnTick="TimerRefresh_Tick"> </asp:Timer> It is connected to an asp:UpdatePanel on the ...

Adding an active class to a link tag depending on the current URL and custom Vanity URLs - here's how!

I have a functioning code snippet, but it seems to be missing a crucial part when dealing with URLs such as www.mysite.com/home/. It works perfectly fine if the URL ends with index.aspx, like www.mysite.com/home/index.aspx, but fails when that part is omit ...

Utilize JQuery's .load() function to transmit JSON data to your Flask server

I am attempting to utilize JQuery's .load() function in order to transmit data to my Flask server and then, with that information, display a <div> that is loaded into the element making the request. This is what my code snippet looks like: $(&qu ...

The usage of arrow functions in ReactJS programming

I'm working on a React component that has the following structure: import React, { PropTypes, Component } from 'react'; import { Accordion, Panel, PanelGroup, Table } from 'react-bootstrap'; const FormCell = ({ data }) => ( ...

JavaScript Conversion of Characters to ASCII Values

After converting a string input into a split array, I now need to convert that split array into ASCII for evaluation. Can someone provide guidance on how to do this? ...

When a function is transferred from a parent component to a child component's Input() property, losing context is a common issue

I have encountered an issue while passing a function from the parent component to the child component's Input() property. The problem arises when the parent's function is called within the child component, causing the this keyword to refer to th ...

I am unable to use the "@" symbol to search for files in the Next platform

Recently, I used @/ to find and import files in Next JS. Due to an issue, I deleted my node modules folder and reinstalled all the packages. After that deletion, @/ stopped functioning properly and I had to change it to ../ instead. This is how my jsconf ...

Troubles encountered with switching npm registry

In my Vue 2.7 project with vuetify, I initially installed dependencies using a custom local npm registry, acting as a proxy to the default npm. As the project has expanded, I've started using git actions to deploy to a development server, with varying ...

Error: An attempt to make changes to a database that does not permit mutations has resulted in an InvalidStateError

I am facing an issue while attempting to initiate a transaction within the then() function. An exception is thrown when I try to do so. Below is the code snippet in question: open.onsuccess = function (e1) { var dbase = e1.target.result; $.get("https://w ...

Oops! The program encountered an issue where it was unable to access the properties of an undefined variable, specifically while trying to

When creating a custom validation function in Angular, I encountered an issue where using a variable within the validation would result in an error: "ERROR TypeError: Cannot read properties of undefined (reading 'file')". This occurred when chang ...

Tips to store Google fonts in the assets directory

I've included this link in my styles.scss @import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap'); While it works locally, the API fails on production or is blocked. How can I host it within my p ...

Why is this component not functioning properly?

I am struggling with making a function to add a component dynamically when I click a button, similar to the code below. However, my attempt at creating a separate method for adding the component instead of using an inline expression is not working. Can som ...

Getting js.map Files to Function Properly with UMD Modules

I am experiencing an issue with debugging TypeScript files in Chrome and Firefox. Specifically, when trying to debug the MapModuleTest.ts file, the debugger seems to be out of sync with the actual JavaScript code by two lines. This discrepancy makes settin ...

Is there a way to ensure a dialog box is positioned in the center of the window?

After adjusting the dimensions of my jQuery UI dialog box with the following code: height: $(window).height(), width: $(window).width(), I noticed that it is no longer centered on the window. Do you have any suggestions on how I can recenter it? ...

Provide a parameter for a function's callback

I am attempting to utilize lodash's debounce function to delay the onChange event. See the code snippet below. import React, { useState, useEffect, useCallback } from "react"; import { TopBar } from "@shopify/polaris"; import { debounce } from "lodas ...

Primeng - Concealed dropdown values within a scrollable table header

Recently, I integrated Primeng p-table with a filter and frozen column feature (with one column being fixed while the others are movable). However, I encountered an issue with the select dropdown in the header. When I try to open the dropdown, the values a ...

Is there a way to sort through nested objects with unspecified keys?

I'm looking to extract specific information from a nested object with unknown keys and create a new array with it. This data is retrieved from the CUPS API, where printer names act as keys. I want to filter based on conditions like 'printer-stat ...

Ways to examine a JavaScript Bound Function

Can a JavaScript bound function be inspected somehow? I need to be able to return a bound function from a function, and when unit testing, I'd like to verify the bound function's target, boundThis, and boundArgs. These properties seem to be inte ...

Adjust the background to scroll to the bottom of the image first and then change it to be fixed

Here is the code I have written: body{ margin:0; padding:0; line-height: 1.5em; background-image: url(http://fehlbelichtet.stefanwensing.de/wp-content/uploads/sites/6/2016/04/alte-strasse-endlos.jpg); background-repeat:no-repeat; background-attachment: ...

Permit the use of HTML tags within a CSS-only tooltip

I have created a unique CSS tooltip. <span data-tooltip="The security code is a 3-digit number<br />on the back of your Visa or Mastercard debit or credit card, or a 4-digit number on the front of your American Express card.">Help</span> ...