Dan*_*mos 10 reactjs server-side-rendering next.js
问候 Stack Overflow 社区!我使用以下 CSS 在我的 Next.js 项目中使用了一些自定义字体:
@font-face {
font-family: OpenSans;
font-display: swap;
src: url(./OpenSans-Regular.woff2) format('woff2');
}
Run Code Online (Sandbox Code Playgroud)
问题是 Lighthouse 审计它告诉我预加载这些.woff2文件,但它们正在被 Next.js 散列。我不知道如何为字体添加link标签rel="preload"。
我在哪里可以告诉 Next.js 预加载这些字体?
谢谢!
Hen*_*ren 18
在较新版本的 Next.js 中,这个答案不再相关。但如果您仍在使用旧的 Next.js 版本(应用程序路由器之前),这可能很有用。
问题出在 Next.js 中,如果将字体文件放在 public 之外的任何其他文件夹中,字体文件就会被编译。因此,如果您将它们放在公共文件夹中并手动引用它们,则可以使用如下所示的链接预加载。
将它们包含在 Head 标记中,并指定不同字体类型的类型以实现浏览器兼容性。确保在 CSS 中正确引用它们。
<Head>
<link
rel="preload"
href="/fonts/yourfont/yourfont.woff2"
as="font"
crossOrigin=""
type="font/woff2"
/>
</Head>
Run Code Online (Sandbox Code Playgroud)
@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");
}
Run Code Online (Sandbox Code Playgroud)
对于外部字体,您只需在 head 组件中添加预加载链接即可;
<link rel="preload" href="https://fonts.googleapis.com/css?family=Play&display=swap" as="font" />
Run Code Online (Sandbox Code Playgroud)
至于文件夹中的内部字体public,这需要;
file-loader配置中next.config.js,这是为了解析散列文件名您可以在下面找到我的示例;
我创建了一个Layout.tsx包装我的其他组件的组件,其主要目的是不会有重复的元标记- 但这与问题无关。
这是我的代码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>
);
}
Run Code Online (Sandbox Code Playgroud)
布局.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>
);
};
Run Code Online (Sandbox Code Playgroud)
下一个环境.d.ts
...
declare module "*.woff";
declare module "*.woff2";
...
Run Code Online (Sandbox Code Playgroud)
next.config.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;
},
};
Run Code Online (Sandbox Code Playgroud)
您可以通过添加以下内容_document.js在<Head>组件内部预加载它们:
<link
rel="preload"
href="/fonts/inter-var-latin.woff2"
as="font"
type="font/woff2"
/>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5475 次 |
| 最近记录: |