You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 17:55:14