Teachnique
      CourseRoadmaps
      Login

      Introduction

      Project SetupCLI

      IntroductionAPP RouterTemplateLoading UIError Handling404 Page

      Linking and Navigating

      Dynamic RoutesRoute groupsParallel RoutesIntercepting Routes

      Route handlersCacheCommon Questions

      Middleware

      CSRSSR & SSGISR

      React Server ComponentsServer-Side Rendering

      SuspenseStreaming

      Server & Client ComponentServer vs. Client ComponentBest Practices

      Server-Side Rendering Strategies

      Data Fetching & Caching & RedirectThird-Party Request Libraries on the Server SideBest Practices

      Request MemoizationData CacheFull Route CacheRouter Cache

      Server Actions IFormServer Actions IIOptimistic Update

      Tailwind CSSCSS-in-JSSass

      Environment VariablesAbsolute Imports& Module Path AliasesRoute Segment Config

      Image & LCPImage IImage IIOptimizing IOptimizing II

      Next FontFont ParameterApply Styles

      Feedback

      Submit request if you have any questions.

      Course
      Apply Styles

      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.

      Apply Styles

      1. Using className

      So far, we've primarily discussed adding styles through the className property:
      import { Inter } from 'next/font/google';
      
      const inter = Inter({
      subsets: ['latin'],
      });
      
      export default function RootLayout({ children }) {
      return (
      <html lang="en" className={`${inter.className}`}>
      <body>{children}</body>
      </html>
      );
      }
      When you access the className property of the font object, it returns a read-only CSS class name:
      For example, inter.className might return a value like __className_a64ecd, which corresponds to a class automatically generated by Next.js in the layout.css file:
      .__className_a64ecd {
      font-family: '__Inter_a64ecd', '__Inter_Fallback_a64ecd';
      font-style: normal;
      }
      
      @font-face {
      font-family: '__Inter_a64ecd';
      //...
      }
      
      @font-face {
      font-family: '__Inter_Fallback_a64ecd';
      //...
      }

      2. Using style

      In addition to className, you can also use style, which returns a read-only style object. Here's an example:
      // layout.js
      import { Inter } from 'next/font/google';
      
      const inter = Inter({
      subsets: ['latin'],
      });
      
      export default function RootLayout({ children }) {
      return (
      <html style={inter.style}>
      <body>{children}</body>
      </html>
      );
      }
      The generated HTML code would look like this:
      (Insert image showing the generated style attributes)

      3. Using CSS Variables

      We've already covered CSS variables in detail, so we won't go into it again here.

      Common Issues

      7.1. Using Multiple Fonts

      You can import and use multiple fonts in two main ways:

      Method 1: Utility Function

      Create a utility function to export the fonts, then import the desired fonts wherever you need them and apply the className. This approach ensures that fonts are preloaded only when used.
      Export two font objects:
      javascriptCopy code// app/fonts.js
      import { Inter, Roboto_Mono } from 'next/font/google';
      export const inter = Inter({
      subsets: ['latin'],
      display: 'swap',
      });
      export const roboto_mono = Roboto_Mono({
      subsets: ['latin'],
      display: 'swap',
      });
      
      Import and use them as needed:
      javascriptCopy code// app/layout.js
      import { inter } from './fonts';
      export default function Layout({ children }) {
      return (
      <html lang="en" className={inter.className}>
      <body>
      <div>{children}</div>
      </body>
      </html>
      );
      }
      
      // app/page.js
      import { roboto_mono } from './fonts';
      export default function Page() {
      return (
      <>
      <h1 className={roboto_mono.className}>My page</h1>
      </>
      );
      }
      

      Method 2: CSS Variables

      Create a CSS variable that can be used with your preferred CSS strategy:
      javascriptCopy code// app/layout.js
      import { Inter, Roboto_Mono } from 'next/font/google';
      const inter = Inter({
      subsets: ['latin'],
      variable: '--font-inter',
      display: 'swap',
      });
      const roboto_mono = Roboto_Mono({
      subsets: ['latin'],
      variable: '--font-roboto-mono',
      display: 'swap',
      });
      export default function RootLayout({ children }) {
      return (
      <html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}>
      <body>
      <h1>My App</h1>
      <div>{children}</div>
      </body>
      </html>
      );
      }
      
      The final implementation would be:
      (Insert image showing CSS variable usage)
      As seen, two CSS variables are declared: --font-roboto-mono and --font-inter. When you need to style text with these fonts, use the corresponding variable:
      cssCopy code// app/global.css
      html {
      font-family: var(--font-inter);
      }
      h1 {
      font-family: var(--font-roboto-mono);
      }
      

      7.2. Integrating with Tailwind CSS

      next/font can be used alongside Tailwind CSS by leveraging CSS variables.
      First, declare CSS variables using the variable property:
      javascriptCopy code// app/layout.js
      import './globals.css';
      import { Ma_Shan_Zheng, Roboto_Mono } from 'next/font/google';
      
      const ma_shan_zheng = Ma_Shan_Zheng({
      subsets: ['latin'],
      display: 'swap',
      weight: '400',
      variable: '--font-ma-shan-zheng',
      });
      const roboto_mono = Roboto_Mono({
      subsets: ['latin'],
      display: 'swap',
      variable: '--font-roboto-mono',
      });
      
      export default function RootLayout({ children }) {
      return (
      <html lang="en" className={`${ma_shan_zheng.variable} ${roboto_mono.variable}`}>
      <body>{children}</body>
      </html>
      );
      }
      
      Then, add the CSS variables to your Tailwind CSS configuration:
      javascriptCopy code// tailwind.config.js
      module.exports = {
      content: [
      './src/**/*.{js,ts,jsx,tsx,mdx}',
      ],
      theme: {
      extend: {
      fontFamily: {
      "ma": ['var(--font-ma-shan-zheng)'],
      "mono": ['var(--font-roboto-mono)'],
      },
      },
      },
      plugins: [],
      }
      
      Finally, apply styles to elements using the font- prefix (e.g., font-ma, font-mono):
      javascriptCopy code// page.js
      export default function Page() {
      return <h1 className="font-ma underline">你好,世界!Hello World!</h1>;
      }
      

      7.3. Using a Font Definition File

      When you call the font function, each font instance is managed separately. If multiple places use the same font, it's best to load it in one location and import it as needed. This is where a font definition file comes in handy.
      For example, create a fonts.ts file in the styles directory at the root level and define your fonts:
      javascriptCopy code// styles/fonts.js
      import { Inter, Lora, Source_Sans_3 } from 'next/font/google';
      import localFont from 'next/font/local';
      const inter = Inter();
      const lora = Lora();
      
      const sourceCodePro400 = Source_Sans_3({ weight: '400' });
      const sourceCodePro700 = Source_Sans_3({ weight: '700' });
      
      const greatVibes = localFont({ src: './GreatVibes-Regular.ttf' });
      export { inter, lora, sourceCodePro400, sourceCodePro700, greatVibes };
      
      You can now use these definitions in your code:
      javascriptCopy code// app/page.js
      import { inter, lora, sourceCodePro700, greatVibes } from '../styles/fonts';
      export default function Page() {
      return (
      <div>
      <p className={inter.className}>Hello world using Inter font</p>
      <p style={lora.style}>Hello world using Lora font</p>
      <p className={sourceCodePro700.className}>
      Hello world using Source_Sans_3 font with weight 700
      </p>
      <p className={greatVibes.className}>My title in Great Vibes font</p>
      </div>
      );
      }
      
      To make accessing the font definition file easier, you can define a path alias in tsconfig.json or jsconfig.json:
      jsonCopy code// tsconfig.json
      {
      "compilerOptions": {
      "paths": {
      "@/fonts": ["./styles/fonts"]
      }
      }
      }
      
      You can now use it like this:
      javascriptCopy code// app/about/page.js
      import { greatVibes, sourceCodePro400 } from '@/fonts';
      
      4o