React hook to load fonts

Posted on 2022-06-11 in Trucs et astuces

If you need to load a specific font in a component, you can use this hook. It will return true when the fonts are loaded. It relies on the document.fonts API to load the fonts. If the fonts are already loaded, the promise will be fulfilled immediately and the component should be "immediately" re-rendered.

import { useEffect, useState } from "react";

export const useFonts = (...fontNames: string[]) => {
    const [isLoaded, setIsLoaded] = useState(false);

    useEffect(() => {
        // Inspired by https://stackoverflow.com/a/60138011
        if (!document || !document.fonts) {
        // eslint-disable-next-line no-console
        console.warn("Browser does not support document.fonts API");
        return;
        }

        Promise.all(fontNames.map((fontName) => document.fonts.load(`16px "${fontName}"`))).then(() => {
        setIsLoaded(true);
        });
    }, [fontNames]);

    return isLoaded;
};

Example usage:

const areFontsLoaded = useFonts("Mistral", "Freestyle Script");

if (!areFontsLoaded) {
  return <Loader />;
}