TL;DR
Font fingerprinting is the use of font availability or text-rendering measurements to help distinguish browser environments. Fonts can reflect operating-system defaults, language support, and installed software, but a font signal does not identify a person on its own. A collector usually needs to interpret it alongside other observations and a reference population.
The important distinction is between a directly assigned identifier and a measured characteristic. A site can store a random cookie value and look it up later. Font fingerprinting instead measures something about rendering and compares the result with previous observations. If many users have the same font configuration, that measurement provides little distinction within that group.
The browser resolves a requested font family, selects glyphs, shapes text, and produces layout or raster output. A measurement script can observe the result without learning every internal detail of that process. Different probes reveal different properties, so the output of a width test should not be described as a complete font fingerprint.
Set a font stack such as a candidate family followed by monospace, measure a chosen string, then compare it with monospace alone. If the candidate changes the measured width, it affected the rendered metrics for that string under those conditions. Repeat with several fallback families and strings to reduce dependence on one coincidental width match.
The Canvas measureText() API returns TextMetrics, including width. It does not return an installed-font list or a confidence score about identity. A script that labels every width difference as a unique user is making an inference the API does not establish.
A page may load a web font, so measuring before and after loading can produce different results in the same environment. A requested family can also lack some glyphs, causing fallback within a string. Keep the test page free of external font imports, wait for its known font-loading state, and use documented probe strings.
Do not implement font detection as a boolean call to document.fonts.check(). MDN documents that a nonexistent font can still return true because no unresolved matching font load is needed. That result cannot be reinterpreted as proof that the named font is installed.
The Local Font Access API can expose local font metadata in supporting browsers, subject to secure-context, permission, and policy restrictions. Do not assume every site can silently enumerate fonts through that API. Also do not assume denying that permission prevents ordinary rendering measurements.
This JavaScript measures three candidate names against three generic fallback families using two strings. Add a pre element with id output to a controlled test page, then run the script after the document exists. It makes no network request and does not ask for local-font enumeration permission.
async function fontProbe() {
await document.fonts.ready;
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("2D canvas unavailable");
const texts = ["mmmmmmWWWWWWiiiiii", "0123456789 fi ffi"];
const bases = ["monospace", "serif", "sans-serif"];
const candidates = ["Arial", "Times New Roman", "__missing_font_7f9c__"];
const width = (font, text) => {
ctx.font = `32px ${font}`;
return ctx.measureText(text).width;
};
return candidates.map(name => {
const comparisons = bases.flatMap(base => texts.map(text => ({
base, text,
fallbackWidth: width(base, text),
candidateWidth: width(`"${name}", ${base}`, text)
})));
return {
candidate: name,
differsFromFallback: comparisons.some(x =>
Math.abs(x.candidateWidth - x.fallbackWidth) > 0.01),
comparisons
};
});
}
fontProbe().then(result => {
document.querySelector("#output").textContent = JSON.stringify(result, null, 2);
});
The script was run in Chrome 157 on a local page. In that run, Arial and Times New Roman changed at least one fallback comparison; the deliberately missing family matched its fallback comparisons. Those results establish that the probe executed and that its control behaved as expected in that environment. They do not establish a universal installed-font detector or a population-level uniqueness rate.
The 0.01 threshold is a tolerance chosen for this demonstration, not a validated classification threshold. If measurements are close, inspect the underlying numbers instead of rounding them into a confident label. Keep the raw vector for debugging and avoid collecting a larger font inventory than your test requires.
A useful test distinguishes repeatability from distinctiveness. Repeatability asks whether the same environment produces the same result under the same conditions. Distinctiveness asks how often different environments share that result. A width vector can be stable and still be common across many users.
| Observation | Reasonable interpretation | Unsupported conclusion |
|---|---|---|
| Candidate differs from fallback | Requested family changed measured metrics | The visitor has been uniquely identified |
| Candidate equals fallback | No difference observed for these probes | The font cannot exist |
| Same Profile changes after update | Rendering conditions or implementation may have changed | A different person must be using it |
| Two Profiles have equal vectors | These probes do not distinguish them | Every browser signal is identical |
The Chromium analysis of identification mechanisms describes fonts among many device and rendering characteristics. It is useful for the signal taxonomy, but its historical browser examples should not be copied as current support claims or current identification rates.
For a QA team, font differences can explain layout changes, clipped labels, or screenshots that differ between machines. For a privacy assessment, they reveal one source of observable environment information. For an account-operations team, unexplained changes are a reason to inspect environment configuration, not an automatic explanation for every login challenge.
Use a controlled comparison record: browser build, Profile identifier, probe-page version, candidate families, strings, and output vector. Re-run after planned environment changes. If a site rejects a session while the metric vector remains stable, investigate account permissions, network conditions, storage, and other signals instead of repeatedly changing fonts.
Nstbrowser manages browser environments as Profiles with configurable fingerprint settings. Its documentation lists fonts among the parameters relevant to browser fingerprints. A saved Profile provides an environment to inspect repeatedly while keeping intended settings organized. That is useful for comparing a controlled probe before and after an authorized configuration change. The public setting description does not establish the internal font-generation algorithm or prove resistance to a particular site's checks.
Create a test environment using the Profile creation guide. Review the available options in Profile and fingerprint settings, then open the same controlled probe page before and after a normal restart. Record the actual client and kernel versions; the documentation contains older version examples that should not define a current test configuration.
Use group settings to review shared configuration and extension choices that could affect the test page. This guide's probe was tested in an ordinary local browser, not an authenticated Nstbrowser Profile; validate the actual Profile separately before drawing product-specific conclusions.
Keep test conditions stable, preserve useful measurements, and describe precisely what changed. A passing checker result is a snapshot under that checker's chosen probes. It does not guarantee anonymity, account safety, or acceptance by every website.
Q: Does font fingerprinting require a cookie?
No. Rendering measurements can be collected without using a stored cookie identifier, although a site may combine both mechanisms.
Q: Does document.fonts.check() list installed fonts?
No. It checks whether the requested font specification can be used without unresolved matching font loads; even a nonexistent family can return true.
Q: Will clearing cookies change my measured font widths?
Cookie deletion does not itself replace the font or rendering stack. A specific page may still change its own font loading or settings based on state, so control the test page when comparing results.
Q: Can one font test prove a Profile is safe to use?
No. It measures one set of rendering properties. Account access, website policies, proxy behavior, and other browser signals require separate checks.