跳至內容

字型最佳化

next/font 將自動最佳化您的字型(包含自訂字型),並移除外部網路請求,以提升隱私和效能。

🎥 觀看: 深入瞭解如何使用 next/fontYouTube (6 分鐘)

next/font 包含針對任何字型檔案的內建自動自我託管。這表示您可以最佳化地載入網頁字型,且不會發生版面配置偏移,這要歸功於使用的底層 CSS size-adjust 屬性。

這個新的字型系統也讓您可以方便地使用所有 Google Fonts,同時兼顧效能和隱私。CSS 和字型檔案會在建置時下載並與其餘靜態資源一起自我託管。瀏覽器不會向 Google 發送任何請求。

Google Fonts

自動自我託管任何 Google Font。字型包含在部署中,並從與您的部署相同的網域提供服務。瀏覽器不會向 Google 發送任何請求。

首先從 next/font/google 匯入您想要使用的字型作為函式。我們建議使用可變字型,以獲得最佳效能和彈性。

若要在所有頁面中使用字型,請將其新增至 /pages 下的_app.js 檔案,如下所示

pages/_app.js
import { Inter } from 'next/font/google'
 
// If loading a variable font, you don't need to specify the font weight
const inter = Inter({ subsets: ['latin'] })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={inter.className}>
      <Component {...pageProps} />
    </main>
  )
}

如果您無法使用可變字型,則需要指定粗細

pages/_app.js
import { Roboto } from 'next/font/google'
 
const roboto = Roboto({
  weight: '400',
  subsets: ['latin'],
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={roboto.className}>
      <Component {...pageProps} />
    </main>
  )
}

您可以使用陣列來指定多個粗細和/或樣式

app/layout.js
const roboto = Roboto({
  weight: ['400', '700'],
  style: ['normal', 'italic'],
  subsets: ['latin'],
  display: 'swap',
})

小知識:對於包含多個單字的字型名稱,請使用底線 (_)。例如,Roboto Mono 應匯入為 Roboto_Mono

<head> 中套用字型

您也可以使用字型,而無需包裝器和 className,方法是將其注入到 <head> 中,如下所示

pages/_app.js
import { Inter } from 'next/font/google'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <>
      <style jsx global>{`
        html {
          font-family: ${inter.style.fontFamily};
        }
      `}</style>
      <Component {...pageProps} />
    </>
  )
}

單頁使用

若要在單頁上使用字型,請將其新增至特定頁面,如下所示

pages/index.js
import { Inter } from 'next/font/google'
 
const inter = Inter({ subsets: ['latin'] })
 
export default function Home() {
  return (
    <div className={inter.className}>
      <p>Hello World</p>
    </div>
  )
}

指定子集

Google Fonts 會自動子集化。這會減少字型檔案的大小並提升效能。您需要定義要預先載入的這些子集。如果preloadtrue,但未指定任何子集,則會導致警告。

這可以透過將其新增至函式呼叫來完成

pages/_app.js
const inter = Inter({ subsets: ['latin'] })

請參閱Font API 參考以取得更多資訊。

使用多種字型

您可以在應用程式中匯入和使用多種字型。您可以採取兩種方法。

第一種方法是建立一個實用工具函式,該函式匯出一個字型,匯入它,並在需要的地方套用其 className。這可確保字型僅在渲染時預先載入

app/fonts.ts
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',
})

在上述範例中,Inter 將全域套用,而 Roboto Mono 可以根據需要匯入和套用。

或者,您可以建立一個CSS 變數,並將其與您偏好的 CSS 解決方案一起使用

app/global.css
html {
  font-family: var(--font-inter);
}
 
h1 {
  font-family: var(--font-roboto-mono);
}

在上述範例中,Inter 將全域套用,而任何 <h1> 標籤都將使用 Roboto Mono 設定樣式。

建議:保守地使用多種字型,因為每種新字型都是用戶端必須下載的額外資源。

本地字型

匯入 next/font/local 並指定本地字型檔案的 src。我們建議使用可變字型,以獲得最佳效能和彈性。

pages/_app.js
import localFont from 'next/font/local'
 
// Font files can be colocated inside of `pages`
const myFont = localFont({ src: './my-font.woff2' })
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={myFont.className}>
      <Component {...pageProps} />
    </main>
  )
}

如果您想要對單一字型系列使用多個檔案,src 可以是陣列

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',
    },
  ],
})

請參閱Font API 參考以取得更多資訊。

搭配 Tailwind CSS

next/font 可以透過CSS 變數Tailwind CSS 一起使用。

在以下範例中,我們使用來自 next/font/google 的字型 Inter(您可以使用 Google 或本地字型中的任何字型)。使用 variable 選項載入您的字型以定義您的 CSS 變數名稱,並將其指派給 inter。然後,使用 inter.variable 將 CSS 變數新增至您的 HTML 文件。

pages/_app.js
import { Inter } from 'next/font/google'
 
const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
})
 
export default function MyApp({ Component, pageProps }) {
  return (
    <main className={`${inter.variable} font-sans`}>
      <Component {...pageProps} />
    </main>
  )
}

最後,將 CSS 變數新增至您的Tailwind CSS 設定

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
    './app/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-inter)'],
        mono: ['var(--font-roboto-mono)'],
      },
    },
  },
  plugins: [],
}

您現在可以使用 font-sansfont-mono 實用工具類別來將字型套用至您的元素。

預先載入

當在您網站的頁面上呼叫字型函式時,它不會全域可用,也不會在所有路由上預先載入。相反地,字型僅根據其使用的檔案類型,在相關的路由上預先載入

  • 如果它是獨特的頁面,則會在該頁面的獨特路由上預先載入
  • 如果它在自訂 App 中,則會在 /pages 下網站的所有路由上預先載入

重複使用字型

每次您呼叫 localFont 或 Google 字型函式時,該字型都會作為應用程式中的一個實例託管。因此,如果您在多個檔案中載入相同的字型函式,則會託管同一個字型的多個實例。在這種情況下,建議執行以下操作

  • 在一個共用檔案中呼叫字型載入器函式
  • 將其匯出為常數
  • 在您想要使用此字型的每個檔案中匯入常數