简体   繁体   English

如何使用 NextJS 使用自托管字体?

[英]How to use self-hosted fonts face using NextJS?

Fonts using NextJS使用 NextJS 的字体

I have read different topics about how to use self-hosted fonts with NextJS.我已经阅读了关于如何在 NextJS 中使用自托管字体的不同主题。

What I got [ wait ] compiling... when I did:我得到的[ 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');
}

No error, or else just compiling... I've read ( stackoverflow/57590195 ) which says we should use a static path like没有错误,或者只是编译......我读过( stackoverflow/57590195 )它说我们应该使用静态路径,比如

@font-face {
    font-family: 'font';
    src: url('./static/fonts/Montserrat-Medium.woff2') format('woff2');
}

but that solution does not work at all.但该解决方案根本不起作用。 It almost seems to work fine, because the error (or the compelling waiting) stops.它几乎看起来工作正常,因为错误(或强制等待)停止了。 But if you look closer your font is not loaded.但是如果你仔细观察,你的字体没有加载。

Then I tried fontfaceobserver, I understood quickly that the problem would be the same.然后我尝试了 fontfaceobserver,我很快明白问题是一样的。 Because you have to use font-face and you cannot use it with NextJS.因为你必须使用font-face并且你不能将它与 NextJS 一起使用。

After I downloaded next-font I have read the doc and looked at the github exemples .下载 next-font 后,我阅读了文档并查看了 github 示例

Here is my next.config.js inspired of theirs.这是我的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;
            }
        })
    )
);

My path to fonts public/static/fonts .我的字体路径public/static/fonts

And here is how I tried to use it.这就是我尝试使用它的方式。

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

Solutions I found我找到的解决方案

Read more one the github issue阅读更多关于 github 的问题

EDIT:编辑:

I tried to adapt what Jesper We did .我试图适应Jesper We所做的事情。

I have created /public/static/fonts/fonts.css and /public/fonts/allMyfont.ttf then I imported in _var.scss to use it with sass variable @import "/public/static/fonts/fonts.css";我创建了/public/static/fonts/fonts.css/public/fonts/allMyfont.ttf然后我导入了 _var.scss 以将它与 sass 变量一起使用 @import "/public/static/fonts/fonts.css"; import style.scss my var $font and import "my/path/style.scss" to my index.js (compling for ever)导入 style.scss 我的 var $font 并将“my/path/style.scss”导入我的 index.js(永远编译)

After I tried a closer way still /public/static/fonts/fonts.css with my fonts in the same folder.在我尝试更接近的方式后,仍然/public/static/fonts/fonts.css与我的字体在同一个文件夹中。 Then in my index.js.然后在我的 index.js 中。 But that one does nothing.但是那个什么都不做。

Here the code in live CodeSandBox这是实时CodeSandBox中的代码

This is what I usually do:这是我通常做的:

  1. Put the fonts in public/static somewhere将 fonts 放在公共/静态某处

  2. In the same folder as the fonts put a CSS file where the fonts are declared在与 fonts 相同的文件夹中,放置一个 CSS 文件,其中声明了 fonts

CSS file example /public/fonts/style.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;
}

Import this css in _document.js ( docs ):_document.js ( docs ) 中导入此 css:

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

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

I have tried on the latest version of next.js "next": "10.0.8"我已经尝试过最新版本的 next.js "next": "10.0.8"

Added all of the fonts to public/fonts folder and used in globals.css with font faces.将所有 fonts 添加到 public/fonts 文件夹并在带有字体的globals.css中使用。

I think the paths you are using in font face might not be correct but i am not sure about the structure of the code.我认为您在字体中使用的路径可能不正确,但我不确定代码的结构。

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

Afterwards you can use it font-family: 'Open Sans'之后你可以使用它font-family: 'Open Sans'

Here is a related blog post if you want to read more about如果您想了解更多信息,这是一篇相关的博客文章

On v12.0.4 , using tailwindcss I had to try few fs changes but landed up with the following that worked.v12.0.4 上,使用 tailwindcss 我不得不尝试一些 fs 更改,但得到了以下有效的方法。 In addition I used both custom fonts and google fonts.此外,我使用了自定义 fonts 和谷歌 fonts。

You can also test w/o tailwind but testing inline global CSS:您还可以在没有顺风的情况下进行测试,但要测试内联全局 CSS:

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

import '../public/styles.css' # didn't work outside public/ import '../public/styles.css' # 在 public/ 之外不起作用

# 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>

Holy Tip: These days you need not serve multiple font files as variable fonts are widely supported by using just one file.温馨提示:如今,您无需提供多个字体文件,因为仅使用一个文件即可广泛支持变量 fonts Moreover, the newer font format woff2 has a better compression ratio and is again widely supported .此外,较新的字体格式woff2具有更好的压缩比,并再次得到广泛支持

  1. Put font file in /public/fonts/ folder将字体文件放在/public/fonts/文件夹中

  2. Add it to _document.tsx file so that it's fetched for all pages:将其添加到_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. Mention in global CSS file:在全局 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. Tell browser to cache this font file for a long time (~1yr) to avoid unnecessary re-downloads for subsequent site visits.告诉浏览器将此字体文件缓存很长时间(~1 年),以避免为后续站点访问进行不必要的重新下载。
    Add headers to next.config.json :将标题添加到next.config.json
module.exports = {
  async headers() {
    return [
      {
        source: "/fonts/inter-var-latin.woff2",
        headers: [
          {
            key: "Cache-Control",
            value: "public, max-age=31536000, immutable",
          },
        ],
      },
    ];
  },
};

Above implementation can be seen on this commit of my personal site .上面的实现可以在我个人网站的这个提交上看到。

Moving the /fonts/OpenSans.otf directory to public/fonts/OpenSans.otf.将 /fonts/OpenSans.otf 目录移动到 public/fonts/OpenSans.otf。 Works for me.为我工作。

Now I can use anywhere with this line:现在我可以在任何地方使用这条线:

@font-face {
      font-family: 'OpenSans';
        src: url('/fonts/OpenSans.otf') format('opentype');
        font-weight: normal;
        font-style: normal;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM