How to Detect Font Awesome on Any Website (API Guide)
Font Awesome is the icon toolkit that quietly ended up on a large slice of the web. A developer drops in one stylesheet or one script tag, writes <i class="fas fa-user"></i>, and gets a full icon set without touching an SVG file. That single-line install is exactly why detecting it is useful and exactly why detecting it is trickier than it looks: the install can arrive as CSS, as JavaScript, or as a hosted Kit, and only some of those leave a signal a server-side fetch can read.
This guide covers all of it: what Font Awesome actually is, the four distinct signals it leaves in a page, which of those a scan can and cannot see, how to check a site by hand, and how a single DetectZeStack API call returns Font Awesome alongside the rest of the stack. We will be precise about the false negatives, because with Font Awesome they are common enough to matter.
What Font Awesome Is and Why Detecting It Matters
Font Awesome is a font and icon toolkit based on CSS and Less. It ships thousands of vector icons in two delivery modes: a classic web-font build, where a stylesheet maps class names onto glyphs in a custom font file, and an SVG-with-JS build, where a script replaces <i> placeholders with inline SVG at runtime. Both are in heavy use, and the mode a site picks changes what you can detect.
A confirmed Font Awesome detection is a small but genuinely informative front-end signal:
- It marks a template-driven or CMS-driven front end. Font Awesome is the default icon set bundled into an enormous number of WordPress themes and page builders. Seeing it next to Elementor or a theme fingerprint usually means the site was assembled rather than hand-built — useful qualification for agencies selling design or migration work.
- It is a render-blocking asset in the critical path. A web-font icon set pulls a CSS file plus one or more font files before first paint. For anyone selling performance work, "loads the full Font Awesome CSS to render nine icons" is a concrete, demonstrable finding rather than a generic recommendation.
- It says something about dependency habits. A page that pulls Font Awesome from a public CDN has a different third-party surface than one that self-hosts a subset. That distinction is the qualifier for supply-chain and subresource-integrity tooling.
The same detection pipeline works for any technology DetectZeStack recognizes. We have companion guides for the font-delivery services Adobe Fonts and Typekit; the fingerprint changes, the workflow does not.
The Signals That Reveal Font Awesome in a Page
Font Awesome does not sit in DNS, in response headers, or in a TLS certificate. It is entirely a page-body technology, which means every signal lives in the HTML the server hands back or in the JavaScript that runs afterwards. There are four of them, and they are not equally visible.
CSS link tags (font-awesome.min.css, fontawesome-free, cdnjs and jsDelivr paths)
The classic web-font install is a stylesheet reference. It shows up in the <head> in one of a handful of recognizable shapes:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/all.min.css">
<link rel="stylesheet" href="/wp-content/themes/acme/assets/css/font-awesome.min.css">
The constant is the string font-awesome or fontawesome in the URL, sometimes under the @fortawesome npm scope. This is the most common install in the wild — and, as we will cover below, it is the one an API scan is most likely to miss, because the fingerprint that matches Font Awesome keys on script sources rather than stylesheet links.
Script sources (kit.fontawesome.com and Kit loader script URLs)
The SVG-with-JS build and the hosted Kit both arrive as a script tag, and this is the strongest machine-readable signal:
<script src="https://kit.fontawesome.com/a1b2c3d4e5.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/js/all.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/js/all.min.js"></script>
<script src="/assets/js/fontawesome-all.js"></script>
The Kit loader is worth calling out separately. A Kit URL is kit.fontawesome.com/<kit-id>.js, where the Kit ID is an opaque identifier tied to an account. The Kit resolves which icon subset and which version to serve on the server side, which means the URL tells you a Kit is in use but deliberately tells you nothing about the version.
JavaScript globals (___FONT_AWESOME___ and FontAwesomeCdnConfig)
Once the SVG-with-JS build has executed, it leaves globals on window. ___FONT_AWESOME___ is the internal registry the library uses for its icon definitions and config; FontAwesomeCdnConfig appears on CDN-delivered builds. Both are reliable confirmations — but only inside a running browser. A server-side HTTP fetch downloads the script tag without executing it, so these globals never materialize in an API scan. Treat them as a DevTools tool, not a scanning one.
Where the version number comes from, and when it is missing
Font Awesome does not announce its version in a header, a meta tag, or a generator comment. Every version signal you can get comes from the asset URL itself:
| URL Shape | Example | Version Readable? |
|---|---|---|
| cdnjs path | /ajax/libs/font-awesome/6.5.1/css/all.min.css | Yes — 6.5.1 in the path |
| npm-scoped CDN | @fortawesome/[email protected]/js/all.min.js | Yes — after the @ |
| Kit loader | kit.fontawesome.com/a1b2c3d4e5.js | No — opaque Kit ID |
| Self-hosted | /assets/css/font-awesome.min.css | Usually no |
In practice this means the version field on a Font Awesome detection comes back empty far more often than not. If version data is the thing you actually need — for example to separate Font Awesome 4 sites, which use the old fa fa- class prefix, from version 5 and 6 sites — plan on grepping it out of the asset URL yourself rather than relying on the parsed field.
Manual Detection: View Source and DevTools
Because every signal lives in the page, you can confirm Font Awesome yourself with one command. The broadest single check catches both the CSS and the script variants:
$ curl -s https://example.com | grep -oiE '[^"'"'"']*font-?awesome[^"'"'"']*' | sort -u
https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css
One match is enough to confirm the page loads Font Awesome, and because the pattern captures the whole URL you get the delivery method and often the version for free. To narrow it to the Kit loader specifically:
$ curl -s https://example.com | grep -o 'kit\.fontawesome\.com/[a-z0-9]*\.js'
kit.fontawesome.com/a1b2c3d4e5.js
For the JavaScript-build case, open DevTools on the page and probe the globals directly in the console:
> typeof window.___FONT_AWESOME___
"object"
> typeof window.FontAwesomeCdnConfig
"object"
> document.querySelectorAll('[class*="fa-"]').length
23
That last line is the pragmatic fallback: counting elements carrying an fa- class tells you Font Awesome icon markup is present even when the asset URL has been renamed or bundled into a generic app.css. It only works in a browser, though — and it is exactly the kind of check that does not scale past one site, which is where an API comes in.
Detecting Font Awesome With the DetectZeStack API
When DetectZeStack fetches a page, it scans the HTML for script sources matching the Font Awesome fingerprint — font-awesome, fontawesome, the @fortawesome npm scope, and the *.fontawesome.com/<id>.js Kit loader. A match returns Font Awesome under the Font scripts category at confidence 100, with source: "http", because the evidence came straight from the HTTP response body.
Trying it without an API key using GET /demo
The public demo endpoint needs no API key. It is IP-rate-limited, so use it for spot checks rather than bulk work:
$ curl -s "https://detectzestack.com/demo?url=example.com" \
| jq '.technologies[] | select(.name == "Font Awesome")'
{
"name": "Font Awesome",
"categories": ["Font scripts"],
"confidence": 100,
"description": "Font Awesome is a font and icon toolkit based on CSS and Less.",
"website": "https://fontawesome.com/",
"icon": "Font Awesome.svg",
"source": "http",
"version": "",
"cpe": ""
}
Note the empty version and empty cpe. Neither is an error: Font Awesome rarely exposes a parseable version, and it carries no CPE identifier in the fingerprint data, unlike server-side software such as PHP or WordPress. If you are building security workflows around CPE strings, our guide on detecting vulnerable technologies with CPE covers which technologies do carry one.
Full stack scan with GET /analyze
When you want the whole stack for a domain rather than a filtered slice, call /analyze with your API key. A typical WordPress page that loads Font Awesome from cdnjs comes back like this:
$ curl -s "https://detectzestack.p.rapidapi.com/analyze?url=example.com" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com"
{
"url": "https://example.com",
"domain": "example.com",
"technologies": [
{
"name": "Font Awesome",
"categories": ["Font scripts"],
"confidence": 100,
"description": "Font Awesome is a font and icon toolkit based on CSS and Less.",
"website": "https://fontawesome.com/",
"icon": "Font Awesome.svg",
"source": "http",
"version": "",
"cpe": ""
},
{
"name": "cdnjs",
"categories": ["CDN"],
"confidence": 100,
"description": "cdnjs is a free distributed JS library delivery service.",
"website": "https://cdnjs.com",
"icon": "cdnjs.svg",
"source": "http",
"version": "",
"cpe": ""
},
{
"name": "WordPress",
"categories": ["CMS", "Blogs"],
"confidence": 100,
"description": "WordPress is a free and open-source content management system written in PHP and paired with a MySQL or MariaDB database.",
"website": "https://wordpress.org",
"icon": "WordPress.svg",
"source": "http",
"version": "",
"cpe": "cpe:2.3:a:wordpress:wordpress:*:*:*:*:*:*:*:*"
}
],
"categories": {
"Font scripts": ["Font Awesome"],
"CDN": ["cdnjs"],
"CMS": ["WordPress"],
"Blogs": ["WordPress"]
},
"meta": { "status_code": 200, "tech_count": 3, "scan_depth": "full" },
"cached": false,
"response_ms": 1842
}
The top-level categories map groups every detection by category, so you can pull every icon and font library with .categories["Font scripts"] without iterating the array. The meta object carries the HTTP status_code, the tech_count, and the scan_depth; response_ms and cached sit at the top level.
Watch meta.scan_depth when you are building lists. A value of "full" means the HTTP fetch succeeded and body detection ran. A value of "partial" means the site blocked or timed out the HTTP request and only the DNS and TLS layers completed — and since Font Awesome lives entirely in the body, an absent detection on a "partial" scan tells you nothing at all. Those domains belong in a retry queue, not your rejects file.
Yes or no answer with GET /check?tech=Font Awesome
If all you need is a boolean, /check answers one question about one domain and returns a much smaller payload. The tech match is case-insensitive, and the response echoes back the canonical name:
$ curl -s -G "https://detectzestack.p.rapidapi.com/check" \
--data-urlencode "url=example.com" \
--data-urlencode "tech=Font Awesome" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com"
{
"domain": "example.com",
"technology": "Font Awesome",
"detected": true,
"confidence": 100,
"version": "",
"categories": ["Font scripts"],
"response_ms": 1210,
"cached": false
}
Use --data-urlencode rather than pasting the value into the URL — "Font Awesome" contains a space, and an unencoded space will produce a malformed request.
Scanning a list of domains with POST /analyze/batch
For list building, POST /analyze/batch accepts up to 10 URLs per request and analyzes them concurrently. Each entry carries either a full analysis result, identical in shape to a single /analyze response, or an error for domains that could not be fetched:
$ curl -s -X POST "https://detectzestack.p.rapidapi.com/analyze/batch" \
-H "X-RapidAPI-Key: YOUR_KEY" \
-H "X-RapidAPI-Host: detectzestack.p.rapidapi.com" \
-H "Content-Type: application/json" \
-d '{"urls": ["example.com", "getbootstrap.com", "wordpress.org"]}'
Because each result matches the single-domain shape, the filtering logic is identical whether you scan one domain or a thousand. Here is a complete pipeline using nothing but bash, curl, and jq. It reads domains.txt one domain per line, sends batches of 10, and appends every Font Awesome hit to a CSV along with the tech count and the scan depth:
#!/usr/bin/env bash
# find-font-awesome.sh — filter a domain list down to Font Awesome sites
KEY="YOUR_KEY"
HOST="detectzestack.p.rapidapi.com"
echo "domain,tech_count,scan_depth" > fontawesome_leads.csv
# Process domains.txt in batches of 10 (the /analyze/batch maximum)
xargs -n 10 < domains.txt | while read -r batch; do
urls=$(printf '%s\n' $batch | jq -R . | jq -s '{urls: .}')
curl -s -X POST "https://$HOST/analyze/batch" \
-H "X-RapidAPI-Key: $KEY" \
-H "X-RapidAPI-Host: $HOST" \
-H "Content-Type: application/json" \
-d "$urls" |
jq -r '.results[]
| select(.result != null)
| .result as $r
| select([$r.technologies[].name] | index("Font Awesome"))
| [$r.domain, ($r.meta.tech_count | tostring), $r.meta.scan_depth]
| @csv' >> fontawesome_leads.csv
done
wc -l fontawesome_leads.csv
A 1,000-domain list becomes 100 batch calls. The index("Font Awesome") guard keeps a domain whenever Font Awesome appears in its technology list, and select(.result != null) skips domains that failed to resolve. For a deeper treatment of throughput, retries, and a production Python scanner, see how to batch scan 1,000 websites.
What Font Awesome Tells You About the Rest of the Stack
Font Awesome almost never travels alone, and the technologies it appears next to are usually more commercially interesting than the icon set itself. Three pairings come up constantly:
- Font Awesome plus a CMS. The single most common context is WordPress, where the icon set arrives bundled inside a theme or a page builder. If your list needs CMS sites specifically, filter on both — our guides on finding companies using WordPress and detecting which CMS a site runs cover that layer.
- Font Awesome plus a library CDN. When Font Awesome comes from cdnjs, jsDelivr, or Google Hosted Libraries, the CDN is detected as its own entry in the same scan. That combination marks a team that leans on public CDNs for dependencies rather than bundling them.
- Font Awesome plus a CSS framework. The classic pairing is Bootstrap and jQuery, which together describe a very specific generational profile: a front end built the 2015-2020 way rather than with a modern component framework. If you sell modernization work, that triple is your qualifier.
Common Detection Pitfalls and False Negatives
Font Awesome produces more false negatives than most technologies, and it is worth being blunt about why.
The honest limitation: the fingerprint DetectZeStack matches for Font Awesome keys on the script source. A site that loads Font Awesome purely as a stylesheet — <link rel="stylesheet" href="/css/font-awesome.min.css"> with no accompanying script — is a real Font Awesome install that can still come back with no detection. That is the classic web-font build, and it is common. If CSS-only installs matter for your use case, pair the API scan with a grep over the fetched HTML for the string font-awesome.
Beyond that, four more causes account for most misses:
- Icons injected after load. A Kit script added through a tag manager, or icons rendered client-side by a JavaScript framework, may never appear in the server-rendered HTML a scan fetches.
- Renamed or bundled assets. A build step that inlines Font Awesome into
app.min.cssor a self-hosted subset renamed toicons.cssstrips the identifying string out of the URL entirely. - The JS globals are invisible to a fetch.
___FONT_AWESOME___only exists after the script executes. An HTTP fetch does not execute JavaScript, so that signal is a browser-only confirmation. - Partial scans. As noted above,
meta.scan_depthof"partial"means the body was never read. Check that field before you record a negative.
The practical rule: a Font Awesome detection is strong evidence of presence, and an absent detection is an unknown rather than proof of absence. Build your filters so positives drive action and negatives drive a second look.
Practical Use Cases: Agency Prospecting, Front-End Audits, Performance Reviews
Agency prospecting. Font Awesome plus WordPress plus a page builder is a reliable signature for a site that was assembled from a template. That is a qualified lead for design refresh, migration, or ongoing maintenance work — and the whole triple comes back in one /analyze call, so you can score a domain list in a single pass. Our guide to competitor website technology analysis covers building that scoring layer.
Front-end audits. When you inherit a codebase, "which icon system is actually loading, and how many are loading at once" is a real question. It is not unusual to find Font Awesome and a second icon set both shipping because two different theme layers each pulled one in. A scan across every page template surfaces that in minutes.
Performance reviews. The classic web-font build blocks rendering on a CSS file plus font files. Detecting Font Awesome, then checking whether the site uses the full build or a subset, turns a vague "your fonts are slow" into a specific, quantified finding you can put in a proposal.
Get Your API Key and Start Detecting Font Awesome
The free tier includes 100 requests per month with no credit card — enough to validate the pipeline on a sample of your domain list before scaling up. Sign-up is instant through RapidAPI:
- Get a key at rapidapi.com/mlugoapx/api/detectzestack.
- Spot-check a domain you know:
curl -s "https://detectzestack.com/demo?url=yourdomain.com" | jq '.technologies[].name' - Run the batch script above against your first 100 domains.
Conclusion
Detecting Font Awesome comes down to knowing which of its four signals you can actually reach. The script source is the one an API scan reads, and it returns Font Awesome under the Font scripts category at confidence 100 with source: "http". The stylesheet link is the most common install but the easiest to miss, so pair the scan with a grep when CSS-only sites matter. The JavaScript globals are a DevTools confirmation, not a scanning one. And the version, when it exists at all, lives in the asset URL rather than the parsed version field. Get those four straight and a single /analyze call answers the one-domain question, while /analyze/batch turns a raw domain list into a qualified one.
Related Reading
- How to Detect cdnjs on Any Website — The library CDN that delivers Font Awesome on a large share of sites, detected from the same page body
- Find Companies Using Adobe Fonts — The other half of the web-typography stack, and how its host signature differs
- How to Detect Typekit (Adobe Fonts) on Any Website — Host-signature detection applied to a font CDN (use.typekit.net)
- How to Detect Bootstrap on Any Website — Font Awesome's most frequent companion, and what the pairing says about a front end
- How to Detect jQuery on a Website — The third leg of the classic template-site triple
- Find Companies Using jsDelivr — The npm-scoped CDN that serves @fortawesome packages with the version in the URL
- Find Companies Using Google Hosted Libraries — Another library-delivery CDN detected from script references in the page HTML
- Find Companies Using WordPress — The CMS Font Awesome most often ships inside, via themes and page builders
- How to Batch Scan 1,000 Websites for Tech Stack Data — Deep dive on /analyze/batch throughput, retries, and a Python scanner
Try DetectZeStack Free
100 requests per month, no credit card required. Header, DNS, and TLS detection included on every plan.
Get Your Free API Key