# Testing for local() support with the FontFace API

Sometimes you want to know if a certain font is available on the user's device. This can be used for evil (hello fingerprinting!) but maybe also for good (hello [FaFoFal](/tools/fafofal/)!).

Usually people use rendering text to a hidden "canvas" (e.g. a `div`) and measuring the expected width compared to a default font. ([Example](https://www.samclarke.com/javascript-is-font-available/))

There's a better way - using the `FontFace` constructor:

<pre class="prettyprint">
const hasAvenir = await new FontFace('meh', 'local("Avenir Book")').load().then(
  () =&gt; true,
  () =&gt; false
);
</pre>

What's going on here?

* `meh` is just string, useless in this case
* usually we use `url()` to load an external font file, but here the trick is to use `local()`
* we're trying to load a local font that goes by the name "Avenir Book"
* the `load()` method returns a promise where you can return `true` if the font is available or `false` if there's a `NetworkError` exception. (Funny that it's a _network_ exception for a local load, but that's not really important)

## `local()` vs `font-family`

There are differences between using `local('Font name')` and `font-family: Font name`. See [this writeup](https://calendar.perfplanet.com/2024/fabulous-font-face-fallbacks/) for details. Or [this one](https://highperformancewebfonts.com/read/font-jargon).

In practice for example `font-family: Avenir` works fine across browsers (on systems that have Avenir, e.g. Mac OS), but `local('Avenir')` may not. At the time of writing, it works in Firefox but not in Chrome. However `local('Avenir Book')` works in both.

The code above works just like the browser would when using `local()` for real and not just for testing. If that's what you want (I know I do, for the Fafofal tool) -- great. If not, it's back to measuring widths<i class="circle"><s></s></i>