FontFaceObserver is a lightweight web font loading monitor and detector that efficiently tracks when @font-face fonts become available in the browser. It provides a Promise-based API for monitoring font loading events, supports custom test strings for non-Latin fonts, and configurable timeouts.
npm install fontfaceobserverimport FontFaceObserver from "fontfaceobserver";For CommonJS:
const FontFaceObserver = require("fontfaceobserver");For browser (global):
// FontFaceObserver is available as window.FontFaceObserver
const FontFaceObserver = window.FontFaceObserver;import FontFaceObserver from "fontfaceobserver";
// Create observer for a font family
const font = new FontFaceObserver('My Family', {
weight: 400,
style: 'normal'
});
// Monitor font loading
font.load().then(function () {
console.log('Font is available');
document.documentElement.className += " fonts-loaded";
}, function () {
console.log('Font failed to load');
});
// Custom test string for non-Latin fonts
const chineseFont = new FontFaceObserver('Chinese Font');
chineseFont.load('中国').then(function () {
console.log('Chinese font loaded');
});
// Custom timeout (default is 3000ms)
font.load(null, 5000).then(function () {
console.log('Font loaded within 5 seconds');
});FontFaceObserver uses different detection mechanisms based on browser capabilities:
document.fonts.load() when available (modern browsers)Creates a new font observer instance for monitoring specific font family loading.
/**
* Creates a font observer for the specified font family
* @param {string} family - Font family name to monitor (required)
* @param {Object} descriptors - Font descriptors (optional)
* @param {string} descriptors.style - Font style, defaults to 'normal'
* @param {string} descriptors.weight - Font weight, defaults to 'normal'
* @param {string} descriptors.stretch - Font stretch, defaults to 'normal'
* @param {Window} context - Browser window context, defaults to current window (optional)
*/
new FontFaceObserver(family, descriptors, context);Usage Examples:
// Basic font observer
const font = new FontFaceObserver('Arial');
// Font with descriptors
const boldItalicFont = new FontFaceObserver('Roboto', {
weight: 'bold',
style: 'italic'
});
// Font with all options
const condensedFont = new FontFaceObserver('Open Sans', {
weight: '300',
style: 'normal',
stretch: 'condensed'
}, window);Monitors font loading and returns a Promise that resolves when the font becomes available.
/**
* Monitors font loading and returns a Promise
* @param {string} text - Custom test string for font detection, defaults to 'BESbswy'
* @param {number} timeout - Timeout in milliseconds, defaults to 3000
* @returns {Promise<FontFaceObserver>} Promise that resolves with the observer instance
*/
FontFaceObserver.prototype.load(text, timeout);Usage Examples:
// Basic loading detection
font.load().then(() => console.log('Font loaded'));
// Custom test string for non-Latin fonts
const arabicFont = new FontFaceObserver('Arabic Font');
arabicFont.load('العربية').then(() => console.log('Arabic font loaded'));
// Custom timeout
font.load(null, 10000).then(() => console.log('Font loaded within 10 seconds'));
// Multiple fonts
const fontA = new FontFaceObserver('Font A');
const fontB = new FontFaceObserver('Font B');
Promise.all([fontA.load(), fontB.load()]).then(() => {
console.log('Both fonts loaded');
});Properties available on FontFaceObserver instances.
// Font family name being monitored
fontObserver.family; // string
// Font style descriptor
fontObserver.style; // string
// Font weight descriptor
fontObserver.weight; // string
// Font stretch descriptor
fontObserver.stretch; // string
// Browser window context
fontObserver.context; // WindowFontFaceObserver handles various error conditions:
font.load().then(
function() {
// Font loaded successfully
},
function(error) {
// Font failed to load
console.error('Font loading failed:', error.message);
// Error message format: "3000ms timeout exceeded"
}
);Common error scenarios:
FontFaceObserver works across all major browsers:
The library automatically detects browser capabilities and uses the most efficient detection method available.
For TypeScript users, here are the key type definitions:
interface FontDescriptors {
style?: string;
weight?: string;
stretch?: string;
}
declare class FontFaceObserver {
family: string;
style: string;
weight: string;
stretch: string;
context: Window;
constructor(family: string, descriptors?: FontDescriptors, context?: Window);
load(text?: string, timeout?: number): Promise<FontFaceObserver>;
}