Adding fonts using the next/font
package to your Next.js project allows you to load type-safe and optimized fonts in your Next.js app.
While adding the next/font
package to your Next.js project is relatively straightforward, doing it using the experimental app
directory is a bit more involved: in fact, the current solution in the documentation delays thr loading of global stylesheets, making the font flickering very noticeable. In this tutorial, I will show you how to add fonts to your Next.js project using the app
directory and the new RSC layouts.
Additionally, I will show you how to add fonts to your Tailwind configuration file, so that you can use them in your components.
NB: this is likely a temporary solution until the next/font
package is updated to support the app
directory.
Using the next/font
package
The next/font
package allows us to import Google Fonts and store them locally, imported as Typescript functions.
For example, we can import the popular font Inter
from Google Fonts:
import { Inter as SansFont} from 'next/font/google';
Next, we want to define a client component that we use in the root layout to load the fonts. Since we need to mark it a client
component, we will create a new file.
Then, we use the new function useServerInsertedHTML
from the next/navigation
package to insert the font styles in the <head>
of the page. Since the component does not need to render anything, we return null
.
Below is the full code for the Fonts
component:
'use client';import { Inter as SansFont } from 'next/font/google';import { useServerInsertedHTML } from 'next/navigation';const sans = SansFont({ subsets: ['latin'], variable: '--font-family-sans', fallback: ['system-ui', 'Helvetica Neue', 'Helvetica', 'Arial'], weight: ['300', '400', '500', '600', '700', '800'], display: 'swap',});function Fonts() { useServerInsertedHTML(() => { return ( <style dangerouslySetInnerHTML={{ __html: ` :root { --font-family-sans: '-apple-system', 'BlinkMacSystemFont', ${sans.style.fontFamily}, 'system-ui', 'Segoe UI', 'Roboto', 'Ubuntu', 'sans-serif'; } `, }} /> ); }); return null;}export default Fonts;
Ideally, you'd define your fonts in your Tailwind configuration file assigned to the variable --font-family-sans
:
module.exports = { theme: { fontFamily: { sans: ['--font-family-sans', 'sans-serif'], }, },};
Now, we can add this component to the root layout, so that it is rendered on every page.
import './globals.css';import Fonts from '~/components/Fonts';export default async function RootLayout({ children,}: { children: React.ReactNode;}) { return ( <html lang={'en'}> <Fonts /> <body>{children}</body> </html> );}
Conclusion
In this tutorial, we learned how to add fonts to our Next.js project using the next/font
package and the new RSC layouts. This is a temporary solution since it will probably be fixed by the Next.js team, but for now it's the best way I found to use the next/font
package with the new Next.js app directory.