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

NextJS 14中next/font/google字体在Safari iOS上无法正常显示

Next.js Google Fonts 在 iOS Safari 显示 Times New Roman 的解决办法

问题还原

在 Next.js 项目中通过 next/font/google 引入 Jomolhari、Josefin_Slab、Josefin_Sans 三款字体,Chrome、Firefox、Mac Safari 均正常渲染,但 iOS Safari 会默认 fallback 到 Times New Roman。已尝试本地字体托管、自定义 @font-face、远程 URL 引入等方案,仍未解决。

用户生产环境代码(存在语法问题):

// layout.tsx
import { Jomolhari, Josefin_Slab, Josefin_Sans } from "next/font/google";

const jomolhari = Jomolhari({
  weight: "400",
  subsets: ["latin"],
  variable: "--font-jomolhari",
  display: "swap",
});

const josefinSans = Josefin_Sans({
  subsets: ["latin"],
  variable: "--font-josefin-sans",
  display: "swap",
});

const josefinSlab = Josefin_Slab({
  subsets: ["latin"],

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html
      className={`${jomolhari.variable} ${josefinSans.variable} ${josefinSlab.variable}`}
      lang="en"
    >
      <body className={josefinSlab.className}>
        {children}
      </body>
    </html>
    );
  }

});

解决方案

1. 修复代码语法错误

代码中 josefinSlab 的配置未闭合,且缺少必要参数,同时末尾多了冗余的 });,这会导致字体变量无法正确注册,直接引发 iOS Safari 加载失败。修正后的代码:

import { Jomolhari, Josefin_Slab, Josefin_Sans } from "next/font/google";

const jomolhari = Jomolhari({
  weight: "400",
  subsets: ["latin"],
  variable: "--font-jomolhari",
  display: "swap",
});

const josefinSans = Josefin_Sans({
  weight: ["400", "600"], // 明确指定可用字重
  subsets: ["latin"],
  variable: "--font-josefin-sans",
  display: "swap",
});

const josefinSlab = Josefin_Slab({
  weight: ["400", "600"], // iOS Safari 对字重匹配要求严格,必须明确指定
  subsets: ["latin"],
  variable: "--font-josefin-slab",
  display: "swap",
});

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html
      className={`${jomolhari.variable} ${josefinSans.variable} ${josefinSlab.variable}`}
      lang="en"
    >
      <body className={josefinSlab.className}>
        {children}
      </body>
    </html>
  );
}

2. 强制指定字体 fallback 栈

iOS Safari 有时会因字体匹配失败直接跳转系统字体,需在全局 CSS 中明确字体优先级:

/* global.css */
body {
  font-family: var(--font-josefin-slab), 'Josefin Slab', serif;
}

/* 其他字体的使用场景同理 */
.jomolhari-text {
  font-family: var(--font-jomolhari), 'Jomolhari', serif;
}

同时包含自定义字体变量、字体官方名称和通用 serif/sans-serif 兜底,避免直接跳到 Times New Roman。

3. 本地托管字体并配置 @font-face

若 next/font 自动处理仍有问题,手动下载字体文件托管到项目 public/fonts 目录,然后在 global.css 中配置:

@font-face {
  font-family: 'Josefin Slab';
  src: url('/fonts/JosefinSlab-Regular.woff2') format('woff2'),
       url('/fonts/JosefinSlab-Regular.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Josefin Slab';
  src: url('/fonts/JosefinSlab-SemiBold.woff2') format('woff2'),
       url('/fonts/JosefinSlab-SemiBold.woff') format('woff');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

这种方式完全避开跨域加载问题,iOS Safari 兼容性更好。

4. 调整字体加载策略

iOS Safari 对 font-display: swap 的处理存在差异,可尝试添加预加载标签(在 RootLayout 的 head 中):

<head>
  <link
    rel="preload"
    href="/fonts/JosefinSlab-Regular.woff2"
    as="font"
    type="font/woff2"
    crossOrigin="anonymous"
  />
</head>

提前预加载核心字体,减少加载延迟导致的 fallback。

5. 检查 iOS 隐私设置

部分用户开启“阻止跨站跟踪”会影响 Google Fonts 远程加载,本地托管字体可彻底解决此问题。

内容的提问来源于stack exchange,提问作者Ricardo Nazario

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:44:56