【Next.js】Adobe Fontsに対応してみた

【Next.js】Adobe Fontsに対応してみた

Next.jsTypeScript

おはこんにちばんは。Next.jsにAdobe Fontsに対応してみました。

Adobe fontsで日本語(東アジアの言語)を含むフォントを選択した場合、スクリプトの埋め込みを求められるので、その対応手順になります。

サンプルコードはこちら

実行環境

  • Next.js 10.0.0
  • React 17.0.1

AdobeFontsのプロジェクトIDを環境変数に定義

まずはAdobeFontsでプロジェクトIDを取得してください。

それをルート配下の .env.local に以下のように定義してあげてください。

.env.local
1NEXT_PUBLIC_KID_ID=<PROJECT_ID>

フォントを読み込むスクリプトを定義

これはAdobeFonts公式のサンプルをそのまま利用します。kitIdの部分は環境変数に書き換えています。

サンプルはルート配下にそのスクリプトを作成します。

./adobeLoader
1const adobeLoader = (d) => {
2 var config = {
3 kitId: process.env.NEXT_PUBLIC_KID_ID,
4 scriptTimeout: 3000,
5 async: true,
6 },
7 h = d.documentElement,
8 t = setTimeout(function () {
9 h.className = h.className.replace(/\bwf-loading\b/g, "") + " wf-inactive";
10 }, config.scriptTimeout),
11 tk = d.createElement("script"),
12 f = false,
13 s = d.getElementsByTagName("script")[0],
14 a;
15 h.className += " wf-loading";
16 tk.src = "https://use.typekit.net/" + config.kitId + ".js";
17 tk.async = true;
18 tk.onload = tk.onreadystatechange = function () {
19 a = this.readyState;
20 if (f || (a && a != "complete" && a != "loaded")) return;
21 f = true;
22 clearTimeout(t);
23 try {
24 Typekit.load(config);
25 } catch (e) {}
26 };
27 s.parentNode.insertBefore(tk, s);
28};
29
30export default adobeLoader;

AdobeFontsのスクリプトを読み込む

次にブラウザ側の処理で1度AobeFontsのスクリプトを読み込む必要があるので、_app.tsx のuseEffect で一度実行するようにします。

サーバーサイド側で実行してしまうと、documentが無くて落ちるので注意しましょう。

./pages/_app.tsx
1import adobeLoader from "../adobeLoader";
2
3useEffect(() => {
4 if (process.browser) adobeLoader(document);
5}, [])
6

CSSのフォント指定

最後はCSSを指定するだけです。今回はグローバルに以下のCSSを指定しています。

1font-family: 'fot-tsukuardgothic-std', sans-serif;
2font-style: normal;
3font-weight: 400;
4

チラつき対応

そうなんです。実はこのままだとAobeFontsをロードする前に1度デフォルトのフォントが表示されてしまい、以下のように一瞬チラつきます。

blog image

この対策にはAobeFontsの読み込み完了後、htmlタグに.wf-activeというclassが挿入されるので、以下のように対応すると改善されます。

1html {
2 visibility: hidden;
3}
4html.wf-active {
5 visibility: visible;
6}

これで終了です。お疲れ様でした。

さいごに

今回は知り合いに相談されて色々調べてみましたが、あまり参考となる情報がなかったので取り敢えずで対応してみました。

もっといい方法ある気がするw

参考

https://qiita.com/hirossyi73/items/6551bc32f0d8c2e56092