🦕
Next.js の App Router で FONTPLUS の Web フォントを読み込む
Next.js (App Router) で FONTPLUS の Web フォント読み込みを行う。
使用する Web フォントは FONTPLUS のスマートライセンス・プランのもの。
エンタープライズ・プランだと CSS 経由で読み込めるらしいので、予算規模が大きい場合はこちらを使おう。[1]
クライアントサイドで実行し、外部スクリプトの読み込み後に Web フォントを再度適用をするのがポイント。(後者はよりよい方法があるかもしれない)
Next.js のバージョンは 14.0.2
。
JSX 版のコンポーネント
/components/FontplusLoader.jsx
"use client"
import Script from 'next/script'
export default function FontplusLoader() {
return (
<Script
src="https://webfont.fontplus.jp/accessor/script/fontplus.js?xxxxxxxxx"
strategy="afterInteractive"
onLoad={() => {
if (FONTPLUS) {
FONTPLUS.reload(false);
}
}}
/>
)
}
TSX 版のコンポーネント
処理は変わらず型定義をちゃんとやる。
本体
/components/FontplusLoader.tsx
"use client"
import Script from 'next/script'
export default function FontplusLoader() {
return (
<Script
src="https://webfont.fontplus.jp/accessor/script/fontplus.js?xxxxxxxxx"
strategy="afterInteractive"
onLoad={() => {
if (FONTPLUS) {
FONTPLUS.reload(false);
}
}}
/>
)
}
型定義
/types/fontplus.d.ts
/**
* FONTPLUS の型定義
* JavaScript API: https://fontplus.jp/usage/javascript-api/method
*/
interface FONTPLUS {
config: (options: ConfigOptions) => void;
reload: (init?: boolean) => void;
attachCompleteEvent: (callback: (result: { code: number }) => void) => void;
targetSelector: (selector: string) => void;
load: (
fontdata: Array<{ fontname: string; nickname?: string; text: string }>,
callback: (result: { code: number; time: number; [key: string]: any }) => void,
tagid?: string
) => void;
isloading: () => boolean;
setFonts: (fontfamily: string[], mode?: string[]) => void;
ontimeout: (callback: () => void) => void;
async: () => void;
start: () => void;
size: (size: boolean) => void;
}
interface ConfigOptions {
selector?: string;
complete?: boolean;
callbacks?: { [key: string]: () => void };
timeoutfunc?: () => void;
sync?: boolean;
size?: boolean;
}
// グローバルスコープで FONTPLUS オブジェクトが存在することを明示
declare var FONTPLUS: FONTPLUS;
コンポーネントの読み込み
作成したコンポーネントを layout.tsx
などで読み込む。
/app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="ja">
<head>
<FontplusLoader />
</head>
<body>
{children}
</body>
</html>
)
}
FONTPLUS では </head>
の直前でスクリプトの読み込みを推奨していたので、そのようにした。
Next.js のドキュメントには
You should not manually add <head> tags such as <title> and <meta> to root layouts. Instead, you should use the Metadata API which automatically handles advanced requirements such as streaming and de-duplicating <head> elements.
とあったけれど[2]、Metadata 関連ではないので多分大丈夫そう。
Discussion