【问题标题】:How to use self-hosted fonts face using NextJS?如何使用 NextJS 使用自托管字体?
【发布时间】:2020-09-06 14:17:08
【问题描述】:

使用 NextJS 的字体

我已经阅读了有关如何在 NextJS 中使用自托管字体的不同主题。

我在[ wait ] compiling ... 做的时候得到了什么:

@font-face {
    font-family: 'montserrat';
    src: url('./mypath/Montserrat-Medium.woff2') format('woff2'),
        url('./mypath/Montserrat-Medium.woff') format('woff'),
        url('./mypath/Montserrat-Medium.ttf') format('truetype'),
        url('./mypath/Montserrat-Medium.svg#Montserrat-Medium') format('svg');
}

没有错误,或者只是编译...我读过 (stackoverflow/57590195) 说我们应该使用像

这样的静态路径
@font-face {
    font-family: 'font';
    src: url('./static/fonts/Montserrat-Medium.woff2') format('woff2');
}

但该解决方案根本不起作用。它似乎工作正常,因为错误(或令人信服的等待)停止了。 但是,如果您仔细观察,您的字体并未加载。

然后我尝试了fontfaceobserver,我很快就明白问题会是一样的。因为你必须使用font-face,而不能与NextJS一起使用。

下载下一个字体后,我阅读了文档并查看了the github exemples

这是我的 next.config.js 灵感来自他们的。

const withSass = require('@zeit/next-sass');
const withCSS = require("@zeit/next-css");
const withFonts = require('next-fonts');

module.exports = withFonts(
    withCSS(
        withSass({
            enableSvg: true,
            webpack(config, options) {
                config.module.rules.push({
                    test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
                    use: {
                        loader: 'url-loader',
                        options: {
                            limit: 100000
                        }
                    }
                });
                return config;
            }
        })
    )
);

我的字体路径public/static/fonts

这就是我尝试使用它的方式。

...
function MainIndex() {
    ...
    return (
        <>
        ...
        <style jsx>{`
                @font-face {
                    font-family: 'Montserrat';
                    src: url('./static/fonts/Montserrat-Medium.ttf');
                }
                h1 {
                    font-family: 'Montserrat';
                }
        `}</style>
        </>
    )
}
...

我找到的解决方案

Read more one the github issue

编辑:

我试图适应 Jesper We did 的内容。

我创建了/public/static/fonts/fonts.css/public/fonts/allMyfont.ttf 然后我导入了_var.scss 以将它与sass 变量@import "/public/static/fonts/fonts.css" 一起使用;导入 style.scss my var $font 并将“my/path/style.scss”导入到我的 index.js(永远编译)

在我尝试了一种更接近的方法之后,仍然/public/static/fonts/fonts.css 将我的字体放在同一个文件夹中。然后在我的 index.js 中。但是那个什么都不做。

这里是实时代码CodeSandBox

【问题讨论】:

  • 这里只是一个简短的说明,您不应该在 Web 上使用 TTF,因为它们是未优化的文件。如果您有 TTF,则可以使用 Google 的 woff2 cli 工具(与名为 woff2_compress 的工具捆绑)将 TTF 文件转换为 WOFF2 压缩文件,以便在您的网站上使用。
  • 我在搜索这个主题时犯了一个愚蠢的错误:我字体的文件扩展名是大写的(.TTF 不是 .ttf)????‍♂️

标签: javascript reactjs fonts next.js


【解决方案1】:

这是我通常做的:

  1. 将字体放在 public/static 的某个地方

  2. 在与字体相同的文件夹中放置一个 CSS 文件来声明字体

CSS 文件示例/public/fonts/style.css:

@font-face {
    font-family: 'Italian No1';
    src: url('ItalianNo1-Black.eot');
    src: url('ItalianNo1-Black.eot?#iefix') format('embedded-opentype'), url('ItalianNo1-Black.woff2') format('woff2'), url('ItalianNo1-Black.woff') format('woff');
    font-weight: 900;
    font-style: normal;
}

[更新] 对于 NextJS 的最新版本,导入 CSS 文件的正确位置是在 _app.js (See docs)import 语句中。


旧答案:

将此css导入_document.js (docs):

render() {
    return (
        <Html>
            <Head>
                <link href="/fonts/style.css" rel="stylesheet"/>
            </Head>

            <body>
                <Main/>
                <NextScript/>
            </body>
        </Html>
    )
}

【讨论】:

  • 因为它是一个名为 _document.js 的文件?在 page/_document.js 中?因为我的档案不同,所以我试图调整你所做的,但在这里工作:/我将编辑我的问题
  • pages/_document.js 是正确的路径。我在答案中添加了指向相关文档的链接。
  • 非常感谢!
  • 不推荐在 _document.js 中使用 link 标签,因为它会对应用中的 CSS 资源加载产生负面影响。 Next.js 的文档在其文档中提到,nextjs.org/docs/messages/no-css-tags。如果您拨打eslint,它将对此发出警告。
【解决方案2】:

我已经尝试过最新版本的 next.js "next": "10.0.8"

将所有字体添加到 public/fonts 文件夹并在 globals.css 中使用字体。

我认为您在字体中使用的路径可能不正确,但我不确定代码的结构。

 @font-face {
  font-family: 'Open Sans';
  src: url('../public/fonts/OpenSans-Light.eot');
  src: url('../public/fonts/OpenSans-Light.eot?#iefix') format('embedded-opentype'),
  url('../public/fonts/OpenSans-Light.woff2') format('woff2'),
  url('../public/fonts/OpenSans-Light.woff') format('woff'),
  url('../public/fonts/OpenSans-Light.ttf') format('truetype');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

之后你可以使用它font-family: 'Open Sans'

如果您想了解更多信息,这里是related blog post

【讨论】:

    【解决方案3】:

    v12.0.4 上,使用 tailwindcss 我不得不尝试一些 fs 更改,但最终得到了以下有效的方法。此外,我同时使用了自定义字体和谷歌字体。

    您也可以在没有顺风的情况下进行测试,但要测试内联全局 CSS:

    # _app.js
    <div style={{ fontFamily: "Inter"}}>
        <Component {...pageProps} />
    </div>
    

    import '../public/styles.css' # 在公共之外无法使用/

    # styles.css
    # font files are in the same directory
    @font-face {
        font-family: 'Avenir';
        src: url('avenir/avenir-light.woff') format('woff');
        font-weight: 100;
        font-style: normal;
    }
    
    # tailwind.config.js
        theme: {
            extend: {
                fontFamily: {
                    sans: ['Avenir', 'Inter', ...defaultTheme.fontFamily.sans],
                    title: ['Avenir', 'Inter', ...defaultTheme.fontFamily.sans]
                }
            }
        },
    
    # _document.js
    <Head>
        <link
            href="https://fonts.googleapis.com/css2?family=Inter&display=optional"
            rel="stylesheet"
        />
    </Head>
    

    【讨论】:

      【解决方案4】:

      Holy Tip:现在你不需要提供多个字体文件,因为 variable fontswidely supported 只使用一个文件。而且,较新的字体格式woff2具有更好的压缩比,又是widely supported

      1. 将字体文件放入/public/fonts/文件夹

      2. 将其添加到_document.tsx 文件,以便为所有页面获取它:

      export default class MyDocument extends Document {
        render(): JSX.Element {
          return (
            <Html>
              <Head>
                <link
                  rel="preload"
                  href="/fonts/inter-var-latin.woff2"
                  as="font"
                  type="font/woff2"
                  crossOrigin="anonymous"
                />
              </Head>
              ...
      
      1. 在全局 CSS 文件中提及:
      @font-face {
          font-family: "Inter";
          font-style: normal;
          font-weight: 100 900;
          font-display: optional;
          src: url(/fonts/inter-var-latin.woff2) format("woff2");
        }
      
      1. 告诉浏览器将此字体文件缓存很长时间(~1 年),以避免为后续站点访问进行不必要的重新下载。
        将标题添加到next.config.json:
      module.exports = {
        async headers() {
          return [
            {
              source: "/fonts/inter-var-latin.woff2",
              headers: [
                {
                  key: "Cache-Control",
                  value: "public, max-age=31536000, immutable",
                },
              ],
            },
          ];
        },
      };
      
      

      上面的实现可以在我的personal site的这个commit上看到。

      【讨论】:

        猜你喜欢
        • 2019-12-26
        • 2020-11-02
        • 2019-07-03
        • 2022-08-06
        • 2015-03-17
        • 2021-04-05
        • 1970-01-01
        • 2023-02-20
        • 1970-01-01
        相关资源
        最近更新 更多