reactjs 使用Next.js预加载自定义字体

vaqhlq81  于 2022-12-22  发布在  React
关注(0)|答案(3)|浏览(440)

问候Stack Overflow社区!我在我的Next.js项目中使用了一些自定义字体,使用了以下CSS:

@font-face {
  font-family: OpenSans;
  font-display: swap;
  src: url(./OpenSans-Regular.woff2) format('woff2');
}

问题是灯塔审计告诉我要预加载这些.woff2文件,但它们被Next.js散列了。我不知道如何为字体添加link标签和rel="preload"
我可以在哪里让Next.js预加载这些字体?
谢谢你!

k97glaaz

k97glaaz1#

问题在于Next.js,如果你把字体文件放在public之外的任何文件夹中,字体文件都会被编译。所以如果你把它们放在public文件夹中,然后手动引用它们,你可以像下面这样使用链接预加载。
将它们包含在Head标签中,并为浏览器兼容性指定不同的字体类型。确保在css中也正确引用它们。

<Head>
<link
        rel="preload"
        href="/fonts/yourfont/yourfont.woff2"
        as="font"
        crossOrigin=""
        type="font/woff2"
      />
</Head>
@font-face {
   font-family: "YourFont";
   font-style: normal;
   font-weight: 900;
   src: url('/fonts/yourfont.woff2') format("woff2"),
   url('/fonts/yourfont.woff') format("woff"),
   url('/fonts/yourfont.ttf') format("truetype"),
   url('/fonts/yourfont.svg#yourfont') format("svg");
}
k5hmc34c

k5hmc34c2#

您可以通过添加以下内容将它们预加载到_document.js<Head>组件中:

<link
  rel="preload"
  href="/fonts/inter-var-latin.woff2"
  as="font"
  type="font/woff2"
/>
4bbkushb

4bbkushb3#

对于外部字体,您可以简单地在head组件中添加预加载链接;

<link rel="preload" href="https://fonts.googleapis.com/css?family=Play&display=swap" as="font" />

至于public文件夹中的内部字体,这需要;

  • next.config.js中的file-loader配置,用于解析哈希文件名
  • 字体的类型定义
  • 然后把它导入你的大脑

你可以在下面找到我的样本;
我创建了一个Layout.tsx,它 Package 了我的其他组件,其主要目的是不存在重复的 meta标记-但这与问题无关。
这是我在Next@10.0.5中的代码-预加载外部和内部字体。

应用程序tsx

function App({ Component, pageProps }: AppProps): JSX.Element {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
      <Hydrate state={pageProps.dehydratedState}>
        <Provider store={store}>
          <main className="main-container position-relative" data-testid="main-container">
            <HeaderComp />
            <Layout>
              <Component {...pageProps} />
            </Layout>
            <FooterComp />
            <ScrollToTop />
          </main>
        </Provider>
      </Hydrate>
    </QueryClientProvider>
  );
}

布局.tsx

import fontGilroyBold from "@assets/fonts/gilroy/Gilroy-Bold.woff";

const Layout: React.FunctionComponent = ({ children }) => {
  return (
    <div className="content font-play position-relative">
      <Head> {* next/head *}
        {/* ...metaTags */}
        <link rel="preload" href={fontGilroyBold} as="font" />
        <link rel="preload" href="https://fonts.googleapis.com/css?family=Play&display=swap" as="font" />
      </Head>
      {children}
    </div>
  );
};

下一环境d.ts

...
declare module "*.woff";
declare module "*.woff2";
...

下一个配置js

const nextConfig = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    /**
     * Override some of the existing loaders
     */
    // ...

    /**
     * Font imports in the code repository will be resolved as relative path
     */
    config.module.rules.push({
      test: /gilroy\/.+\.(woff|woff2)$/,
      use: {
        loader: "file-loader",
        options: {
          /** Stolen configuration from pre-existing "config.module.rules[2]" */
          outputPath: "static/fonts/gilroy/",
          publicPath: "/_next/static/fonts/gilroy/",
          limit: 1,
        },
      },
    });

    return config;
  },
};

相关问题