Open5
next/font/googleからエイリアスを作ろうとして挫折した話
やりたきこと
FigmaからOutline Text: OffでSVGとしてExportしてきた(プラグインではなく標準のExport)ファイルを加工せずにNextJS v14+App Router環境下で使いたい。
SVGからExportしてきたファイルにtextタグの属性としてフォント名(font-family)が書いてある。
で、NextJSの標準的な外部フォント使用方法はnext/fontであり、Zen Kaku Gothic NewとRadleyを使ってるので、これをSVG側でも使ってくれたらハッピーである。
問題
じゃあそれをどのように解決するかというと、next/font/googleにはvariable属性を指定することでCSS変数としてexportしてくれる仕組みがある
// layout.tsx
export const ZenKakuGothicNew = Zen_Kaku_Gothic_New({
weight: ["400", "500"],
subsets: ["latin"],
display: "swap",
preload: true,
variable: "--font-zen-kaku-gothic-new"
});
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html>
<body className={`${ZenKakuGothicNew.variable}`}>{children}</body>
</html>
);
}
// styles.css
@font-face {
font-family: "Zen Kaku Gothic New";
src: local(var(--font-zen-kaku-gothic-new));
}
解決策1
じゃあどうすんべとして考えたのが以下。
next/font/googleにはvariable属性を指定することでCSS変数としてexportしてくれる仕組みがあるのでそれを使って"Zen Kaku Gothic New"というfont-family名をエイリアスとしてnext/font/googleに中継してやればいいじゃんという
// layout.tsx
import { Zen_Kaku_Gothic_New } from "next/font/google";
export const ZenKakuGothicNew = Zen_Kaku_Gothic_New({
weight: ["400", "500"],
subsets: ["latin"],
display: "swap",
preload: true,
variable: "--font-zen-kaku-gothic-new"
});
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html>
<body className={`${ZenKakuGothicNew.variable}`}>{children}</body>
</html>
);
}
使うところで以下を読み込めば"Zen Kaku Gothic New"というfont-family名のエイリアスとして使えるはずである。
// styles.css
@font-face {
font-family: "Zen Kaku Gothic New";
src: local(var(--font-zen-kaku-gothic-new));
}
結果
うまくいかない。fallbackフォントが適用されている。
検証
Chromeツールで"Zen Kaku Gothic New"がfont-familyが割当されているのか確認
→ されている
試しにSVG側にNextJSで生成されたfont-familyを指定
→ 表示される
styles.cssのsrcに: local("YuMincho")を指定してみる
→ 適用されない
解決策2
next/font/localのlocalFontを使ってやってみる
// layout.tsx
import { localFont } from "next/font/local";
export const ZenKakuGothicNew = localFont({
src: "../assets/fonts/ZenKakuGothicNew-Medium.ttf",
weight: ["400", "500"],
display: "swap",
preload: true,
variable: "--font-zen-kaku-gothic-new"
});
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html>
<body className={`${ZenKakuGothicNew.variable}`}>{children}</body>
</html>
);
}
結果
解決策1と同じ
解決策3
next/fontを使わずに/public/にフォントファイルを置いてCSSでアクセス
// globals.css
@font-face {
font-family: "Zen Kaku Gothic New";
src: url(/assets/fonts/ZenKakuGothicNew-Medium.ttf);
}
結果
うまくいった
が、これだとnextのフォント最適化を捨て去る事になる...