DEV Community

Cover image for Mastering Web Typography: Building a Real-Time Font Preview Tool with the Local Font Access API.
Muhammad Afsar Khan
Muhammad Afsar Khan

Posted on

Mastering Web Typography: Building a Real-Time Font Preview Tool with the Local Font Access API.

We all know the struggle of choosing a font for a project. You have your design system in Figma, your VS Code open, and you're constantly switching back and forth to see if "Inter" really looks better than "Roboto" at 16px. Wouldn't it be great to just... preview them live, in the browser, alongside your actual content?

In this post, I want to break down the core technical challenges I faced while building FontPreview.online and share the solutions that made it fast, accurate, and developer-friendly.

The Core Challenge: A Million Fonts, One Page
The first hurdle was loading and displaying over 1,000 Google Fonts without crashing the browser. The naive approach-loading every single font stylesheet at once-is a performance nightmare.

The Solution: Lazy Loading with an Intersection Observer.
We load the base UI, but the actual font files are only fetched when a card is about to scroll into view.

// Simplified lazy loading setup
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const card = entry.target;
      loadGoogleFont(card.dataset.fontFamily); // Dynamically create <link> tag
      observer.unobserve(card);
    }
  });
}, { rootMargin: '100px' }); // Start loading 100px before it enters

document.querySelectorAll('.font-card').forEach(card => observer.observe(card));
Enter fullscreen mode Exit fullscreen mode

This "just-in-time" loading keeps the initial page weight low and the interaction smooth.

Leveling Up with the Local Font Access API
This was a game-changer. The window.queryLocalFonts() method allows us to ask a user for permission to read their locally installed fonts. No more guessing if "SF Mono" or "Helvetica Neue" is available!

The Permission Flow is Critical.
You can't just call the function. You need to handle the user's decision gracefully.

Check Support: if ('queryLocalFonts' in window) { ... }

Request and Handle Errors: The call prompts the user. We must handle the NotAllowedError if they deny it, and guide them on how to re-enable it if they change their mind.

De-duplication: The API returns every font variation (e.g., "Arial Bold", "Arial Italic"). We had to map and clean these to present a simple list of unique font families.

This feature is a huge win for developers who want to see exactly how their text will render on a target OS.

Real-Time Accessibility (a11y) is Non-Negotiable
A design tool is useless if it doesn't help you build for everyone. We integrated two levels of contrast checking:

WCAG Ratio: The standard (L1 + 0.05) / (L2 + 0.05) formula.

APCA (Accessible Perceptual Contrast Algorithm): This is the future (WCAG 3). It's more nuanced than the simple ratio, taking font weight and size into account. Implementing this was a deep dive into color science, but it provides a much more accurate prediction of readability.

The Stack and Key Takeaways
Vanilla JavaScript: Keeps it lightweight and fast for a core utility tool.

CSS Grid: Made the responsive card layout trivial.

LocalStorage: For persisting user preferences like pinned fonts and recent searches without a backend.

Building a tool like this is a fantastic way to deepen your understanding of the modern web platform. You'll touch on performance APIs, cutting-edge browser features, and the nuanced world of accessibility.

Check out the source code structure on the live site, and if you're working on a typography project, give the tool a spin!

Top comments (0)