Deri Kurniawan
Deri Kurniawan

Reputation: 496

Next JS v13: How to add font-weight variant of google fonts using @next/font

After Next JS v13, @next/font helps for best performance. Before the package existed, before I used the CDN @import google font in my global CSS

/* path: ./styles/global.css */
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800;900&display=swap");

Now I want to migrate and using @next/[email protected]

/* path: ./pages/_app.tsx */
import { Poppins } from "@next/font/google";

const poppins = Poppins({
  weight: "800", // I want this font-weight has 400,500,600,700,800,900
});

function MyApp({ Component, pageProps }) {
  return (
    <>
      <style jsx global>{`
        html {
          font-family: ${poppins.style.fontFamily};
        }
      `}</style>

      <Component {...pageProps} />
    </>
  );
}

I've been try to using array instead:

const poppins = Poppins({
  weight: ["400", "500", "600", "700", "800", "900"],
});

but the font used always 400 only

Using CDN on CSS: Using CDN on CSS look normal

Using @next/[email protected]: Using next font look more lighter

I want to make the font-weight has 400,500,600,700,800,900 similar like CDN on my CSS. How to make it work and keep it simple? | Expecting an answer on how to use @next/font to add multiple font weights at once.

Thanks

Upvotes: 18

Views: 24440

Answers (5)

prsnt
prsnt

Reputation: 101

For the next.js version:- "13.4.9". If you're using variable fonts then you need to consider following type config in your next.js -> fonts.ts file (File name you can choose whatever you want.)

fonts.ts

import { Poppins } from "next/font/google";
import { Open_Sans } from "next/font/google";

// Non variable fonts.
// you have to specify array of weight

const poppins = Poppins({
  weight: ["400", "900"],   
  display: "swap",
  subsets: ["latin"],
  variable: "--poppins-font",
});

// For variable fonts.
// you have to specify weight= "variable" value only.

const open_sans = Open_Sans({
  weight: "variable",
  style: ["italic", "normal"],
  display: "swap",
  subsets: ["latin"],
  variable: "--open-sans-font",
});

export { poppins, open_sans };

Usage:- in external .scss

layout.tsx

import {poppins, open_sans } from "@/lib/fonts";


export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en" className={`${poppins.variable} ${open_sans.variable}`}>
      <body className={`light`}>
        {children}
      </body>
    </html>
  );
}


_typography.scss

$font = var(--open-sans-font), sans-serif;
body {
  font-family: $font-1;
}

h1 {
   font-weight: 800;
 }

h2 {
   font-weight: 600;
}


Hope this can answer your query or anyone new to next.js font user!

Upvotes: 10

Deri Kurniawan
Deri Kurniawan

Reputation: 496

Before the feature was released in the latest version of Next.js (as of the date of this post), it was not possible to fill the weight object with an array. However, the current version of Next.js (v13.4.x) now supports using an array instead.

const poppins = Poppins({
  weight: ["400", "500", "600", "700", "800", "900"],
});

Available docs: https://nextjs.org/docs/pages/api-reference/components/font

Upvotes: 19

user2640244
user2640244

Reputation: 11

To specify the weight you can try like this:

import { Megrim } from "next/font/google";
const megrim = Megrim({ weight: "400", subsets: ["latin"] });

Another example:

import { Roboto } from 'next/font/google'
const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
})

Upvotes: 1

maxeth
maxeth

Reputation: 1515

What fixed it for me was adding display: "block", "swap" or "fallback" as the font-display option, because for the default value "optional" the browser was omitting to set the font and/or the font-weight for some reason (perhaps too long loading time or potential layout shift).

// pages/_app.js
import { Nunito } from "@next/font/google";

const nunito = Nunito({
  subsets: ["latin"],
  display: "fallback", // <--
});

But, using "block" obviously could make the site feel less fast, and "swap"/"fallback could cause some noticeable layout shifting, so the default behavior of optionally applying fonts is meant to be beneficial for UX and probably not so crucial for websites with "conventional fonts".

Here are more infos on font-display options

Edit: In my case, the cause of this issue was importing non-modular css (e.g. import "swiper/css") somewhere in a deeply nested component, which applied some font-family and/or font-weight styles which caused this unexpected behavior. If you do this too, try converting the css to a css module.

Upvotes: 2

Ty Fiero
Ty Fiero

Reputation: 31

According to the next docs, you can enter "a range of values if it's a variable font such as '100 900'."

Have you tried something like '400 900', to import all of the weights between 400 and 900 for your case? Or you can pass an array of specific font weights you want.

Upvotes: 3

Related Questions