Как импортировать локальные шрифты на веб-сайт Gatsby?

#css #gatsby #webfonts

#css #gatsby #webfonts

Вопрос:

Для начала, я знаю, что это, вероятно, глупо. Шрифты всегда доставляют мне проблемы, почему-то такую обычную вещь действительно нелегко найти. Все онлайн-руководства делают это очень простым (включая собственный Gatsby), никто на самом деле не охватывает потенциальные проблемы.

Я использую это руководство, оно простое, но оно дает представление: объявите @font-face в отдельном файле CSS, импортируйте этот файл в свое приложение. Итак, вот моя структура:

 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, и они действительно загружаются, поэтому файл есть в комплекте, но не шрифты. Дайте мне знать, если какая-либо другая информация поможет.

Ответ №1:

Вы можете попробовать это?

 @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');
}
 

Комментарии:

1. Это сработало! Я попробовал несколько вариантов, и все дело было в формате. Что будет local делать функция? Предпочитаете локальный шрифт, если он установлен?

2. если у вас есть локальные файлы, описывающие ваше семейство шрифтов, то он не выполняет url функцию

Ответ №2:

Я также боролся с локальными шрифтами. Наконец-то я закончил с проектами Typography и 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";
 

Это работает как шарм! Все загружается с вашего домена.

Встроить шрифты в кодировке base64 в CSS

Еще один фрагмент, если вы хотите встроить шрифты в кодировке Base64 в свой css в качестве ссылки на данные ( url(data:font/woff;base64,... ). 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 amp;amp; 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)
}