Skip to content

Instantly share code, notes, and snippets.

@HaNdTriX
Last active June 3, 2024 22:07
Show Gist options
  • Save HaNdTriX/1ddbcceff65ca375940474faf3430564 to your computer and use it in GitHub Desktop.
Save HaNdTriX/1ddbcceff65ca375940474faf3430564 to your computer and use it in GitHub Desktop.
Concepts of simple font loader using react suspense.
function wrapPromise(promise) {
let status = "pending";
let result;
let suspender = promise.then(
r => {
status = "success";
result = r;
},
e => {
status = "error";
result = e;
}
);
return {
read() {
if (status === "pending") {
throw suspender;
} else if (status === "error") {
throw result;
} else if (status === "success") {
return result;
}
}
};
}
const loadFont = async fontFamily => {
const fontFace = new FontFace(fontFamily, `url(/api/font/${fontFamily}.ttf)`);
const loadedFontFace = await fontFace.load();
document.fonts.add(loadedFontFace);
};
const fontMap = new Map();
const useFont = fontFamily => {
if (!fontMap.has(fontFamily)) {
const loader = wrapPromise(loadFont(fontFamily));
fontMap.set(fontFamily, loader);
return loader.read();
}
return fontMap.get(fontFamily).read();
};
export default useFont;
@HaNdTriX
Copy link
Author

Usage:

const MyFontComponent = () => {
  useFont('Helvetica')
  return (
    <div>
      This string will only show up if font was loaded.
    </div>
  )
}

const App = () => (
  <React.Suspense fallback='loading font...'>
    <MyFontComponent />
  </React.Suspense>
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment