Adobe FontsはTypekitを利用しているのですが、欧文フォントを使用するだけであればlinkタグで埋め込むことができたり、web-fontloaderなどのライブラリを使用して導入することができます。
ところが和文フォント(東アジアの言語)を使用しようとするとscriptタグでの埋め込みを指定されてしまいます。
<script>
(function(d) {
var config = {
kitId: '######',
scriptTimeout: 3000,
async: true
},
h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
})(document);
</script>
そのページで使われている文字だけを動的にサブセット化する(ダイナミックサブセット)ためにスクリプトが用意されているんですね。
和文フォントは本当に重いのでいちいち全部読み込んでいたら確かに大変です。
今回はこの読み込みコードから自前の関数を用意してフォントをロードする方法となります。
Contents
AdobeFontsからプロジェクトIDを取得する
まずはAdobeFontsのタグを用意します。プロジェクトIDがわかれば良いです。
赤枠の部分がプロジェクトID(kitId)になるので控えておきましょう。
埋め込みコードをplugins配下のファイルに定義して関数を作る
続いてpluginsディレクトリの中にadobe-fonts.js
というファイルを作成して下記のように設定します。
/* eslint-disable */
export default function ({ app }, inject) {
const adobeFonts = (d) => {
var config = {
kitId: 'projectId',
scriptTimeout: 3000,
async: true,
},
h = d.documentElement,
t = setTimeout(function () {
h.className =
h.className.replace(/\bwf-loading\b/g, '') + ' wf-inactive'
}, config.scriptTimeout),
tk = d.createElement('script'),
f = false,
s = d.getElementsByTagName('script')[0],
a
h.className += ' wf-loading'
tk.src = 'https://use.typekit.net/' + config.kitId + '.js'
tk.async = true
tk.onload = tk.onreadystatechange = function () {
a = this.readyState
if (f || (a && a != 'complete' && a != 'loaded')) return
f = true
clearTimeout(t)
try {
Typekit.load(config)
} catch (e) {}
}
s.parentNode.insertBefore(tk, s)
}
inject('adobeFonts', adobeFonts)
}
上記のコードのkitId
に先ほど控えたプロジェクトIDを入れます。
ちなみに埋め込みコードをそのまま入れただけなので`/* eslint-disable */`で切っておかないとこんな感じでeslintにめっちゃ怒られますw許して
3:5 error Split initialized 'var' declarations into multiple statements one-var
3:5 error Unexpected var, use let or const instead no-var
22:24 error Expected '!==' and instead saw '!=' eqeqeq
22:43 error Expected '!==' and instead saw '!=' eqeqeq
26:9 error 'Typekit' is not defined no-undef
pluginsでの使用は下記の公式サイトのページからヒントを得ています。
Google アナリティクスを使うには?
injectすることでNuxtアプリケーション全体から共通関数として呼び出すことができるようになります。
injectに関して詳しくはこちら
nuxt.config.jsに作成した関数を登録する
pluginsで作成した関数はnuxt.config.jsで設定することによって利用できるようになります。
pluginsセクションにファイルを登録しましょう。
plugins: [
'~/plugins/adobe-fonts',
],
CSSでフォント指定
フォントをロードする前にCSSでfont-familyを設定しておきましょう。
今回使用しているフォントは下記です。
/* DNP 秀英丸ゴシック Std */
font-family: dnp-shuei-mgothic-std, sans-serif;
font-style: normal;
font-weight: 400;
ベースフォントにしたかったのでbodyに追加しました。
body {
font-family: 'dnp-shuei-mgothic-std', 游ゴシック, 'Yu Gothic', 游ゴシック体, YuGothic, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'Meiryo UI', メイリオ, Meiryo, sans-serif;
font-style: normal;
font-weight: 400;
font-size: 1rem;
line-height: 1.5;
height: 100%;
}
LayoutsからWebフォントを読み込む
ではいよいよ関数を使用してロードしましょう。
ページ全体で読み込ませたいのでLayouts/default.vue
に処理を書きました。
<template>
<div>
<Nuxt />
</div>
</template>
<script>
export default {
mounted() {
this.$adobeFonts(document)
},
}
</script>
レンダリング後に処理を書かないと文字を読み込めないのでmounted()
内に処理を書きます。
injectした関数はthis.$xxx()
で呼び出すことができます。(template内で呼び出す場合はthis不要)
これでAdobeフォントがロードできるようになりました!
チラつき防止もやる
元のフォントが一瞬表示されてからAdobeフォントに切り替わるってことよくありますよね。チラつきって言うみたいです。
こちらはCSSでなんとかできますのでサクッと対応しちゃいましょう。
サイト全体でAdobe Fontsを読み込ませる予定があれば、baseのCSSとかグローバルで設定しているスタイルから設定しても良いと思います。
特定のページでしかAdobe Fontsを使わないという場合は、使用するページごとに下記のスタイルの指定をしてあげるのが良いでしょう。
html {
visibility: hidden;
}
html.wf-active {
visibility: visible;
}
これでチラつきもなく綺麗に表示されていることでしょう!!!やったね!
3/19 追記 読み込みはpages側から
読み込みの部分で訂正があります。(すみません)
レンダリングの順番として、pages → layoutsと呼ばれるので、Adobe Fontsの読み込みはpageごとに呼び出すのが良さそうです。
<script>
export default {
mounted() {
this.$adobeFonts(document)
},
}
</script>
私の環境でチラツキが少し目立っていて、こちらを修正したら目立たなくなりました。
調子乗ってLayoutsで!とか言ってすみませんでした。。
おまけ。試したこと
Adobe Fonts(日本語)をJSフレームワークで使用する方法はググっても本当にいい記事が出てこなくて困っていました。
やっと見つけた下記の記事たちも私の環境ではうまくいかなかったので一応軌跡として載せておきます。(失敗したの私だけ??)
headでscriptタグを読み込ませる
export default {
head: {
script: [
{ src: 'https://use.typekit.net/<PROJECT_ID>.js' }
]
},
}
Typekitを実行
<script>
export default {
mounted() {
Typekit.load({async: true})
}
}
</script>
するとぴえんです。
error 'Typekit' is not defined
独り言
Adobe Fontsは有料だし、使用するケースが少なくてみんなあんまり使わないのかなぁという結論に至りました笑
あんまり記事ないよねぇ