Japanese web fonts tend to become large in delivery size so it is better to check whether the font you want to load already exists in the user’s environment or whether the page is Japanese and then decide whether to serve it.
How to check whether a font is available
You can check whether a target font is usable with FontFace from the CSS Font Loading API. Pass only local("font name") in src and judge by whether load() succeeds. If it succeeds the browser can use a font with that name.
async function hasLocalHiragino() {
if( !( 'FontFace' in window ) ) return false;
const font = new FontFace(
'Local Hiragino',
[
'local("Hiragino Sans W3")',
'local("HiraginoSans-W3")',
'local("Hiragino Kaku Gothic ProN W3")',
'local("HiraKakuProN-W3")'
].join( ', ' )
);
return font.load().then(
() => true,
() => false
);
} This method does not check whether the font is installed on the device. It checks whether the page can use that name. Browser restrictions or differences in the specified font name can still return false even when the font is installed. Even then the prepared web font is simply loaded as usual so there is no display issue.
About variable fonts
For variable fonts Regular and Bold may not have separate names so judging with FontFace.load() is not recommended. A demo is also available to check whether a local font can be used from the browser. (After installing a font you may need to restart the browser.)
Adobe Fonts example
In the next example the Typekit script is added only when the page is Japanese and Hiragino is not available.
const WebFont = {
current: { lang: null },
initialized: false,
init() {
this.current.lang = document.documentElement.lang.toLowerCase().split( '-' )[ 0 ];
this.load();
},
async hasLocalHiragino() {
if( !( 'FontFace' in window ) ) return false;
const font = new FontFace(
'Local Hiragino',
[
'local("Hiragino Sans W3")',
'local("HiraginoSans-W3")',
'local("Hiragino Kaku Gothic ProN W3")',
'local("HiraKakuProN-W3")'
].join( ', ' )
);
return font.load().then(
() => true,
() => false
);
},
async load() {
if( this.initialized ) return;
if( this.current.lang !== 'ja' ) return;
this.initialized = true;
if( await this.hasLocalHiragino() ) return;
const config = {
kitId: '******',
async: true,
inactive: () => {
console.error( 'Adobe Fonts could not be activated.' );
}
};
const script = document.createElement( 'script' );
script.src = `https://use.typekit.net/${ config.kitId }.js`;
script.async = config.async;
script.onload = () => {
try {
window.Typekit.load( config );
} catch( error ) {
console.error( error );
}
};
script.onerror = () => {
console.error( 'Adobe Fonts kit could not be loaded.' );
};
document.head.appendChild( script );
}
};
WebFont.init(); initialized is a flag that prevents running the same process more than once. If Hiragino is available the process stops there. Adobe Fonts is loaded only when it is not available.
Google Fonts example
The next example uses Yomogi Regular. When it is not available weight 400 is loaded from Google Fonts.
const WebFont = {
current: { lang: null },
initialized: false,
init() {
this.current.lang = document.documentElement.lang.toLowerCase().split( '-' )[ 0 ];
this.load();
},
async hasLocalYomogi() {
if( !( 'FontFace' in window ) ) return false;
const font = new FontFace(
'Local Yomogi',
[
'local("Yomogi Regular")',
'local("Yomogi-Regular")'
].join( ', ' )
);
return font.load().then(
() => true,
() => false
);
},
async load() {
if( this.initialized ) return;
if( this.current.lang !== 'ja' ) return;
this.initialized = true;
if( await this.hasLocalYomogi() ) return;
const connection = document.createElement( 'link' );
const stylesheet = document.createElement( 'link' );
connection.rel = 'preconnect';
connection.href = 'https://fonts.gstatic.com';
connection.crossOrigin = 'anonymous';
stylesheet.rel = 'stylesheet';
stylesheet.href = 'https://fonts.googleapis.com/css2?family=Yomogi&display=swap';
stylesheet.onerror = () => {
console.error( 'Google Fonts stylesheet could not be loaded.' );
};
document.head.appendChild( connection );
document.head.appendChild( stylesheet );
}
};
WebFont.init(); When the check returns false Google Fonts is loaded as usual.
References
- CSS Font Loading Module Level 3 – W3C
- CSS Fonts Module Level 4 – W3C
- Embed codes – Adobe Fonts
- Dynamic subsetting & web font serving – Adobe Fonts
- Font events – Adobe Fonts
- CSS API update – Google Fonts
- Get Started with the Google Fonts API – Google Fonts
- ※ The content and code are based on official documentation as of July 17, 2026.
- ※ This article is an AI translation of the Japanese original.