タグ:Google Fonts | Nuxt.js | TypeScript | Vue3
Nuxt3でGoogle Fontsを利用する際に思いの外手間取ったので覚え書き
Nuxt3で利用できる「Nuxt Google Fonts」なるGoogle Fonts専用モジュールと、webフォントを読み込み中の制御モジュールの「fontfaceobserver」を導入
yarn add -D @nuxtjs/google-fonts fontfaceobserver
「nuxt.config.ts」に以下を追記
export default defineNuxtConfig({
modules: [
'@nuxtjs/google-fonts',
],
css: [
'@/assets/fonts/google-fonts.css',
],
googleFonts: {
/* 内部フォントの設定 */
download: true, // Googleソースを直接ダウンロード
base64: false, // CSSファイルに直接エンコード挿入
inject: true, // CSSファイルに直接挿入
overwriting: true, // 複数回ダウンロードしない
fontsDir: '', // フォントをダウンロードするディレクトリ
fontsPath: 'assets/fonts', // importさせるフォントCSSファイルのパス
outputDir: 'assets/fonts', // ダウンロードしたファイルの出力ディレクトリ
stylePath: "google-fonts.css", // 管理CSSファイル(※注意)
/* OPTION項目 */
display: 'swap', // フォントの読み込み中にフォントが変わるのを防ぐ
text: '0123456789\nABCDEFGHIJKLMNOPQRSTUVWXYZ\nabcdefghijklmnopqrstuvwxyz', // プレビュー等で事前にフォントを割り当てる文字
preload: true, // linkタグ`rel="preload"`(事前読み込み)を挿入
prefetch: true, // linkタグ`rel="dns-prefetch"`(DNSのオリジン指定)を挿入
preconnect: true, // linkタグに`rel="preconnect"`(事前接続)を挿入
useStylesheet: true, // linkタグに`rel="stylesheet"`(スタイルシート)を挿入
subsets: ['latin'], // ラテン語、キリル文字、ギリシャ語などサポートする言語を追加
families: {
'Roboto': true,
'Inter': [400, 700],
// ここに必要なフォントを追記していく
}
}
})
families
に公式ページから利用したいフォントを探し追加して行きましょう。
例えば「Noto Sans Japanese」というフォントを利用したい場合は...
families: {
'Noto Sans Japanese': true,
}
// または
families: {
'Noto Sans Japanese': [100, 600, 900],
}
という感じでそのまま追加するか、用意してあるスタイルの中から必要な太さだけをリストとして追記
各設定やオプションは必要に応じて追記しtrue / false
を設定してください。
(textオプションなどは多数のデザインフォントを利用する際に英数字まるごと記述しておくと各フォントのプレビューなどでどんなフォントに変わるわかりやすいです)
設定と必要なフォントの追記が完了するとassets/fontディレクトリ内に以下がダウンロードされます
これでNuxt上でのフォントが利用できるになっているハズ...
公式モジュールだけあってdownloadオプションをONにするだけでAPI経由ではなく直接フォントをダウンロードして管理させる際にもかなり簡単に導入できるメリットもありますが、このモジュールの注意点として、nuxtをビルド(またはコンテナ再起動)をする度に
フォントファイルをダウンロードさせるassetsフォルダ内の構造を初期化する仕様なので、outputDirやstylePathで設定した管理CSSファイルの生成場所を他のファイルが入ってるパスと同じに設定するとディレクトリごと初期化(既存の他ファイルもろとも削除)されてしまいます...これはマジでやられた...
回避策として上記設定でモジュール側に触らせるパスをassets/fonts内に限定させています(管理CSSもここに作成)
(issuesで同様の被害にあった方の投稿がありましたがこの記事を執筆中時点ではノータッチでした)
次にfontfaceobserverをプラグインとして追加。「plugins/fontfaceobserver.ts」を作成
import { defineNuxtPlugin } from '#app';
import FontFaceObserver from 'fontfaceobserver';
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.provide('fontFaceObserver', FontFaceObserver);
});
型定義ファイルとして「types/fontfaceobserver.d.ts」も作成
declare module 'fontfaceobserver';
準備ができたらコンポーネントで使用する際には以下の様なユニーククラスを作成すれば、フォントが適用されます
<style scoped>
.font_oswald { font-family: 'Oswald', sans-serif; }
</style>
ライブラリなどを使って動的な処理で個別フォントを適用する場合は、フォントの読み込みが完了してから処理が行える様にFontFaceObserver用の共通処理を作成します
import FontFaceObserver from 'fontfaceobserver';
/**
* 指定されたフォントがロードされるのを待つ関数
* @param {string} font - ロードするフォントの名前
* @param {Function} callback - フォントがロードされた後に実行するコールバック関数
*/
const loadFont = (fontName: string, callback: Function) => {
const fontObserver = new FontFaceObserver(fontName);
fontObserver.load().then(() => {
console.log(`Font ${fontName} has been loaded`);
callback();
}).catch((error: Error) => {
alert(`「${fontName}」のフォントデータ読み込みに失敗しました`);
console.error(`Error loading font ${fontName}:`, error);
});
}
CANVASライブラリのfabric.jsなどで、動的に選択された対象フォント(selectFontFamily)の読み込みが完了したらテキストオブジェクトをcanvasに追加する場合などはこんな感じで追加が可能です
loadFont(selectFontFamily, () => {
const textObject= new fabric.Textbox('サンプルテキスト', {
fontFamily: selectFontFamily,
fontSize: 20,
});
canvas.add(textObject)
});