Next.js13中@next/font加载报错求助
解决Next.js 13中@next/font加载报错:Font loaders must be called and assigned to a const in the module scope
问题原因
你当前的代码把Ubuntu字体的初始化逻辑放在了sApp组件函数内部,而Next.js的@next/font工具要求字体加载器必须在模块作用域(组件函数外部)调用并赋值给const,不能在组件函数内部执行,这就是触发报错的直接原因。
解决方案
将字体初始化代码移到组件函数外部的模块作用域中,具体步骤如下:
- 把
Ubuntu的调用移到sApp函数定义之前的模块级别位置 - 保持全局样式中对字体族的引用不变
修改后的完整代码
import { useApollo } from "@api/apollo/apolloclient"; import { ApolloProvider } from "@apollo/client"; import { CacheProvider, EmotionCache } from "@emotion/react"; import { Ubuntu } from "@next/font/google"; import "focus-visible/dist/focus-visible"; import { DefaultSeo } from "next-seo"; import { AppProps } from "next/app"; import { ChakraProvider, ColorModeScript } from "@chakra-ui/react"; import theme from "@definitions/chakra/theme"; import { ThemeColorProvider } from "@definitions/context/theme"; import createEmotionCache from "@definitions/utils/createEmotionCache"; import Layout from "@layouts/default"; import "@styles/app.css"; import "@styles/global.scss"; import SEO from "../../next-seo.config"; import { useEffect, useState } from "react"; type ComponentWithPageLayout = AppProps & { Component: AppProps["Component"] & { PageLayout?: React.ComponentType; }; emotionCache: EmotionCache; }; const clientSideEmotionCache = createEmotionCache(); // --- 移到模块作用域的字体初始化 --- const ubt = Ubuntu({ weight: ["300", "400", "500", "700"], style: ["normal", "italic"], }); function sApp({ Component, emotionCache = clientSideEmotionCache, pageProps, }: ComponentWithPageLayout): JSX.Element { const apolloClient = useApollo(pageProps); const AnyComponent = Component as any; const Layoutio = Component.PageLayout as any; const [showChild, setShowChild] = useState(false); useEffect(() => { setShowChild(true); }, []); if (!showChild) { return null; } if (typeof window === "undefined") { return <></>; } else { return ( <> <style jsx global>{` html { font-family: ${ubt.style.fontFamily}; } `}</style> <CacheProvider value={emotionCache}> <ApolloProvider client={apolloClient}> <ThemeColorProvider> <ChakraProvider theme={theme}> <ColorModeScript initialColorMode={theme.config.initialColorMode} /> <DefaultSeo {...SEO} /> {Component.PageLayout ? ( <Layoutio> <AnyComponent {...pageProps} /> </Layoutio> ) : ( <Layout> <AnyComponent {...pageProps} /> </Layout> )} </ChakraProvider> </ThemeColorProvider> </ApolloProvider> </CacheProvider> </> ); } } export default App;
额外优化(适配Chakra UI)
如果你想让Chakra UI的组件也统一使用这个字体,可以修改Chakra的主题配置,把字体族替换成ubt.style.fontFamily:
// 在你的theme文件中 import { extendTheme } from "@chakra-ui/react"; import { Ubuntu } from "@next/font/google"; const ubt = Ubuntu({ weight: ["300", "400", "500", "700"], style: ["normal", "italic"], }); const theme = extendTheme({ fonts: { body: ubt.style.fontFamily, heading: ubt.style.fontFamily, }, }); export default theme;
这样就不需要单独写全局style标签,Chakra会自动应用字体。
内容的提问来源于stack exchange,提问作者Obare13
相关产品推荐
相关产品推荐

