Course
Next Font
Next.js Mastery: From Fundamentals to Full-Stack
Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.
Introduction
In this chapter, we'll dive into the
next/font
component built into Next.js. Compared to traditional methods of using fonts, the next/font
component offers more flexibility and convenience. The use of the font
component is divided into two main areas: Google Fonts and local fonts. Both are implemented through the font
component, though their configurations differ slightly.We'll start by discussing the traditional way of using fonts, then explore the conveniences and optimizations that the
font
component brings. Finally, we'll delve into the details of the font
function's parameters, which you can skim through during learning and revisit during actual project development.1. Traditional Font Usage
Let's begin by reviewing the traditional method of using fonts.
The most basic approach is to specify a custom font using the
@font-face
rule, where the font files can either be remote or local. After defining the font, it can be used within the font-family
property.// global.css@font-face { font-family: "Bitstream Vera Serif Bold"; src: url("https://mdn.github.io/css-examples/web-fonts/VeraSeBd.ttf");}
body { font-family: "Bitstream Vera Serif Bold", serif;}
With services like Google Fonts, you can quickly generate style sheets and use them directly via a
<link>
tag or the @import
rule.Using the
<link>
tag:// layout.jsexport default function Layout({ children }) { return ( <html> <head> <link href="https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap" rel="stylesheet" /> </head> <body> {children} </body> </html> )}
Using
@import
:// globals.css@import url('https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap');
body { font-family: "Ma Shan Zheng", serif;}
This would render the text with the specified font.
2. next/font and Layout Shifts
Next.js includes the
next/font
component to help you manage and use fonts more effectively. The next/font
component automatically optimizes fonts (including custom fonts), for example, by using the CSS size-adjust
property to prevent layout shifts.As mentioned in the chapter on the
<Image>
component, layout shifts can occur when images don't have set dimensions, and similarly, layout shifts can happen when web fonts are loaded. For instance:
In this example, three lines of text each have a
font-size
of 64px, but the actual height differs depending on the font. The size-adjust
property can be used to ensure that each font is displayed at the intended 64px size. Next.js automatically applies this optimization.In addition to preventing layout shifts,
next/font
also facilitates easy use of Google Fonts. The CSS and font files are downloaded during the build process, saved like other static assets, and the browser does not make any requests to Google, which improves both performance and privacy. We'll cover more features in detail later in this chapter.The
next/font
component is split into next/font/google
and next/font/local
, which are used for Google Fonts and local fonts, respectively. We'll discuss each in turn.3. next/font/google
3.1 Usage Example
With
next/font/google
, you no longer need to copy style sheet links from Google Fonts and import them via <link>
or @import
. Instead, you can directly import the font you want to use:// app/layout.js// 1. Import the desired fontimport { Inter } from 'next/font/google';
// 2. Instantiate the font object and set subsets, etc.const inter = Inter({ subsets: ['latin'],});
// 3. Apply the font, inter.className returns a read-only CSS class name for loading the fontexport default function RootLayout({ children }) { return ( <html lang="en" className={inter.className}> <body>{children}</body> </html> );}
Next.js recommends using variable fonts for the best performance and flexibility. If variable fonts aren't an option, you should declare the
weight
(font weight, which refers to the thickness of the font):// app/layout.jsimport { Roboto } from 'next/font/google'; const roboto = Roboto({ weight: '400', subsets: ['latin'],}); export default function RootLayout({ children }) { return ( <html lang="en" className={roboto.className}> <body>{children}</body> </html> );}
3.2 Variable Fonts
What are variable fonts? According to Wikipedia:
OpenType variable fonts are an extension of the OpenType font format introduced in version 1.8, jointly developed by Apple, Microsoft, Google, and Adobe, and officially released on September 14, 2016. Fonts that support this specification can store data for varying font outlines, allowing for the automatic generation of various styles based on the initial font outline. This enables users to freely adjust the appearance of text.
In simpler terms, variable fonts allow you to adjust width, weight, slant, and other properties, enabling a single font to display in multiple styles. Next.js recommends using variable fonts.
You can also specify multiple weights and styles using an array:
// app/layout.jsconst roboto = Roboto({ weight: ['400', '700'], style: ['normal', 'italic'], subsets: ['latin'], display: 'swap',});
If the font name contains multiple words, use an underscore (
_
) to connect them. For example, Roboto Mono should be imported as Roboto_Mono:// app/layout.jsimport { Ma_Shan_Zheng } from 'next/font/google';
const font = Ma_Shan_Zheng({ subsets: ['latin'], weight: '400',});
export default function RootLayout({ children }) { return ( <html lang="en" className={font.className}> <body>{children}</body> </html> );}
3.3 Specifying Subsets
Google Fonts allows you to specify subsets, such as Latin, Cyrillic, or Greek for Roboto Mono. There's no need to load all subsets if you don't need them, which can reduce the font file size and improve performance.
These subsets are preloaded by default (controlled via the
preload
attribute, which we'll cover later). If preload
is set to true
without specifying a subset, a warning will appear. Some fonts have only one default subset, like latin
, which still needs to be specified.
// app/layout.jsconst inter = Inter({ subsets: ['latin'] });
How do you know which subsets a font supports? Simply specify a subset, and if it's not valid, Next.js will inform you of the available subsets:
4. next/font/local
To use local fonts, you can use
next/font/local
and declare the file path with the src
attribute. Next.js still recommends using variable fonts. Here's an example:// app/layout.jsimport localFont from 'next/font/local'; const myFont = localFont({ src: './my-font.woff2', display: 'swap',}); export default function RootLayout({ children }) { return ( <html lang="en" className={myFont.className}> <body>{children}</body> </html> );}
The
src
attribute can also be an array if you're using multiple local font files:const roboto = localFont({ src: [ { path: './Roboto-Regular.woff2', weight: '400', style: 'normal', }, { path: './Roboto-Italic.woff2', weight: '400', style: 'italic', }, { path: './Roboto-Bold.woff2', weight: '700', style: 'normal', }, { path: './Roboto-BoldItalic.woff2', weight: '700', style: 'italic', }, ],});
This approach allows you to manage and load local fonts effectively in your Next.js application.