如何将本地字体导入 Gatsby 网站?

How to import local fonts into a Gatsby website?

首先,我知道这可能很愚蠢。字体总是给我带来麻烦,不知怎的,这么普通的东西,实在是不好找资料。所有在线教程都让它看起来非常简单(包括 Gatsby 自己的),没有人真正涵盖潜在问题。

我正在使用 this guide,它很简单,但它给出了一个想法:在单独的 CSS 文件中声明 @font-face,然后将该文件导入您的应用程序。所以这是我的结构:

src/
┣ assets/
┃ ┗ fonts/
┃   ┣ DMSerifDisplay-Italic.ttf
┃   ┣ DMSerifDisplay-Regular.ttf
┃   ┗ fonts.css
┣ components/
┃ ┣ ...
┃ ┗ layout.tsx
┗ pages/
  ┣ 404.tsx
  ┗ index.tsx

两种字体都在 fonts.css 中导入,如下所示:

@font-face {
  font-family: 'DM Serif Display';
  src: url('./DMSerifDisplay-Regular.ttf') format('ttf');
}
@font-face {
  font-family: 'DM Serif Display';
  font-style: italic;
  src: url('./DMSerifDisplay-Italic.ttf') format('ttf');
}

然后将该文件导入 layout.tsx(这是任何页面的基础):

import React, { FC } from 'react'
import { Header } from './header'
import { Footer } from './footer'
import { GlobalStyles } from './global-styles'
import { ThemeProvider } from 'styled-components'
import { theme } from './sc-theme'
import '../assets/fonts/fonts.css'
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

export const Layout: FC = ({ children }) => {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyles />
      <Header />
      <main>{children}</main>
      <Footer />
    </ThemeProvider>
  )
}

但是,我没有在网络选项卡中看到导入的字体。我尝试将一些样式添加到 fonts.css 中,它们确实加载了,所以文件在包中,但不是字体。让我知道是否有任何其他信息有帮助。

你能试试吗?

@font-face {
  font-family: 'DM Serif Display';
  src: local('DM Serif Display'), url('./DMSerifDisplay-Regular.ttf') format('truetype');
}

@font-face {
  font-family: 'DM Serif Display';
  font-style: italic;
  src: local('DM Serif Display'), url('./DMSerifDisplay-Italic.ttf') format('truetype');
}

我也曾为使用本地字体而苦恼。最后我完成了 Typography and Fontsource 个项目:

npm i \
    typography \
    typography-theme-funston \
    gatsby-plugin-typography \
    react-typography \
    @fontsource/cabin-condensed \
    @fontsource/patua-one

您可以选择使用这两个项目或在您方便的时候独立使用其中的任何一个。

排版

./gatsby-config.js

{
  resolve: "gatsby-plugin-typography",
  options: {
    pathToConfigModule: "./src/utils/typography",
    omitGoogleFont: true, // using local fontsource fonts instead
  },
},

./src/utils/typography.js

import Typography from "typography"
import funstonTheme from "typography-theme-funston"

const typography = new Typography(funstonTheme)

export default typography

字体来源

./gatsby-browser.js

import "./src/css/index.css"

./src/css/index.css

@import "~@fontsource/cabin-condensed/latin-400.css";
@import "~@fontsource/cabin-condensed/latin-700.css";
@import "~@fontsource/patua-one/latin-400.css";

... // other styles you need, e.g. https://fonts.google.com/icons
@import "~@fontsource/material-icons/base-400.css";

这很有魅力!一切都从您的域加载。

在 CSS

中嵌入 base64 编码字体

还有一个片段,如果您希望将 Base64 编码的字体作为数据 link (url(data:font/woff;base64,...) 嵌入到您的 css 中。 URL-loader 支持 limit 选项,但配置它有点棘手。

./gatsby-node.js

exports.onCreateWebpackConfig = ({ stage, getConfig, actions }) => {
  if (stage !== "build-javascript" || process.env.gatsby_executing_command !== "build") {
    return
  }
  const config = getConfig()
  const fontsRegex = /\.(eot|otf|ttf|woff(2)?)(\?.*)?$/
  const fontsLoader = config.module.rules.find((rule) => rule.test && String(rule.test) === String(fontsRegex))
  ;[].concat(fontsLoader.use).forEach((it) => {
    it.options = it.options || {}
    it.options.limit = 100_000 // Embed all Fonts into CSS to reduce outbound connections
  })
  actions.replaceWebpackConfig(config)
}