Font Detector avatar

Font Detector

Pricing

from $0.50 / 1,000 font analyses

Go to Apify Store
Font Detector

Font Detector

Detect fonts used on public web pages. Export font families, Google Fonts references, custom font files, CSS family declarations, source URLs, counts, and page status.

Pricing

from $0.50 / 1,000 font analyses

Rating

5.0

(1)

Developer

Maxime Dupré

Maxime Dupré

Maintained by Community

Actor stats

0

Bookmarked

13

Total users

0

Monthly active users

14 days ago

Last modified

Share

🔎 Find fonts in public web pages

Designers, developers, agencies, and SEO teams can use Font Detector to inspect public pages. It returns one dataset row for each successfully analyzed page with font families, CSS declarations, source URLs, counts, page title, and HTTP status. Use that evidence to review typography, compare sites, and plan a redesign.

Use it for typography audits, redesign research, brand QA, design-system checks, migration planning, and competitor font research. You can run it through the Apify API or schedules, use webhooks and integrations, and export the dataset as JSON, CSV, Excel, XML, RSS, or HTML.

📊 Page font evidence

What you receive

Each saved row covers one successfully analyzed public page. It keeps the final URL, status, page metadata, counts, detected font entries, CSS family values, and public source URLs.

What it helps you review

Compare detected and declared families, see which source type exposed a font, and spot partial analyses when a stylesheet could not be read.

🚀 Analyze a public page list

Run steps

  1. Add one or more public page URLs or bare domains.
  2. Set a page limit when you want to analyze only part of the submitted list.
  3. Run the Actor and open the dataset.

The Actor uses public HTML and linked CSS. It does not need website credentials, design-file access, a browser extension, or a Google Fonts API key. Each failed target gets one short warning. It names the submitted value safely and says processing continues. Unsupported or unavailable targets are skipped, with no dataset row or analyzed-page charge. Other submitted targets continue. A page that loads with an unreadable stylesheet can still produce a partial row.

⚙️ Input

Add public page URLs or bare domains. Use pages that can be opened without a login.

Direct stylesheet URLs, such as links to .css files, are unsupported. They are skipped with one safe warning, no dataset row, and no analyzed-page charge. Valid page targets in the same run can still finish.

Input fields

FieldTypeWhat it does
targetsarray of stringsRequired. Add 1 to 1,000 public page URLs or bare domains, one per item.
maxPagesinteger, optionalCaps the number of submitted targets to analyze. Leave it empty to return all available results until the source is exhausted. The schema sets no fixed upper bound.
requestTimeoutSecsinteger, optionalMaximum wait for each public page or stylesheet request. The default is 20, with a range of 5 to 60.

Input example

This example keeps the public fields from the successful Hosted QA default-input run:

{
"targets": [
"https://www.apple.com",
"https://fonts.google.com",
"https://www.wikipedia.org"
],
"maxPages": 100,
"requestTimeoutSecs": 20
}

🧾 Output

The output schema links to the default dataset view. Each successful page uses the same row shape. A row can have status: "partial" and a degradedReason when one or more linked stylesheets could not be read.

Output fields

FieldTypeWhat it does
finalUrlstringFinal public page URL after redirects.
statusstring (ok or partial)Analysis status. partial means one or more linked stylesheets could not be read.
httpStatusCodeintegerHTTP response status returned for the page.
titlestring or nullPage title when the page provides one.
fontCountintegerNumber of detected font entries on the page.
loadedFontCountintegerNumber of detected font entries that are not system fonts.
declaredFamilyCountintegerNumber of distinct CSS font-family values found in the page and readable stylesheets.
googleFontCountintegerNumber of detected entries classified as Google Fonts.
adobeFontCountintegerNumber of detected entries classified as Adobe Fonts.
customFontCountintegerNumber of detected entries classified as custom fonts.
systemFamilyCountintegerNumber of CSS family values classified as system families.
fontsarray of objectsDetected font entries and the source that exposed each one.
fonts.familystringFont family name found in the source.
fonts.sourceTypestringSource type: font-face, google-fonts, adobe-fonts, preload, or css-family.
fonts.sourceUrlstring or nullPublic font file or font reference URL when available.
fonts.sourceCssUrlstring or nullPage or stylesheet URL that supplied the font evidence.
fonts.formatstring or nullFont file format when the source exposes it.
fonts.weightstring or nullDeclared font weight when CSS exposes it.
fonts.stylestring or nullDeclared font style when CSS exposes it.
fonts.isGoogleFontbooleanWhether the entry is classified as a Google Font.
fonts.isAdobeFontbooleanWhether the entry is classified as an Adobe Font.
fonts.isCustomFontbooleanWhether the entry is classified as a custom web font.
fonts.isSystemFontbooleanWhether the entry is classified as a system or fallback font.
fontFamiliesInCssarray of stringsCSS font-family values found in the page and readable stylesheets.
googleFontsUrlsarray of stringsGoogle Fonts stylesheet URLs exposed by the page or its readable stylesheets.
adobeKitIdsarray of stringsAdobe Fonts or Typekit kit IDs exposed by the page or its readable stylesheets.
stylesheetUrlsarray of stringsStylesheet URLs linked by the page for font analysis.
degradedReasonstring, optionalReason a partial analysis may be incomplete.

Representative complete row

This complete row came from a successful current-beta run for CSS Zen Garden:

{
"finalUrl": "https://csszengarden.com/",
"status": "ok",
"httpStatusCode": 200,
"title": "CSS Zen Garden: The Beauty of CSS Design",
"fontCount": 10,
"loadedFontCount": 9,
"declaredFamilyCount": 4,
"googleFontCount": 8,
"adobeFontCount": 0,
"customFontCount": 1,
"systemFamilyCount": 1,
"fonts": [
{
"family": "Julius Sans One",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.gstatic.com/s/juliussansone/v20/1Pt2g8TAX_SGgBGUi0tGOYEga5WOzHsX2aE.woff2",
"sourceCssUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"format": "woff2",
"weight": "400",
"style": "normal",
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Julius Sans One",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.gstatic.com/s/juliussansone/v20/1Pt2g8TAX_SGgBGUi0tGOYEga5WOwnsX.woff2",
"sourceCssUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"format": "woff2",
"weight": "400",
"style": "normal",
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Julius Sans One",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"sourceCssUrl": "https://csszengarden.com/",
"format": null,
"weight": null,
"style": null,
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Libre Baskerville",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.gstatic.com/s/librebaskerville/v24/kmKWZrc3Hgbbcjq75U4uslyuy4kn0qNccR04_RUJeby2OU36SjNDlufifQ.woff2",
"sourceCssUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"format": "woff2",
"weight": "400",
"style": "italic",
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Libre Baskerville",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.gstatic.com/s/librebaskerville/v24/kmKWZrc3Hgbbcjq75U4uslyuy4kn0qNccR04_RUJeby2OU36SjNNluc.woff2",
"sourceCssUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"format": "woff2",
"weight": "400",
"style": "italic",
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Libre Baskerville",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.gstatic.com/s/librebaskerville/v24/kmKUZrc3Hgbbcjq75U4uslyuy4kn0olVQ-LglH6T17uj8Q4iAANPjuM.woff2",
"sourceCssUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"format": "woff2",
"weight": "400",
"style": "normal",
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Libre Baskerville",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.gstatic.com/s/librebaskerville/v24/kmKUZrc3Hgbbcjq75U4uslyuy4kn0olVQ-LglH6T17uj8Q4iDgNP.woff2",
"sourceCssUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"format": "woff2",
"weight": "400",
"style": "normal",
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "Libre Baskerville",
"sourceType": "google-fonts",
"sourceUrl": "http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic",
"sourceCssUrl": "https://csszengarden.com/",
"format": null,
"weight": null,
"style": null,
"isGoogleFont": true,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": false
},
{
"family": "sans-serif",
"sourceType": "css-family",
"sourceUrl": null,
"sourceCssUrl": "https://csszengarden.com/214/214.css?v=8may2013",
"format": null,
"weight": null,
"style": null,
"isGoogleFont": false,
"isAdobeFont": false,
"isCustomFont": false,
"isSystemFont": true
},
{
"family": "verdemoderna",
"sourceType": "font-face",
"sourceUrl": "https://csszengarden.com/214/verdemoderna.eot",
"sourceCssUrl": "https://csszengarden.com/214/214.css?v=8may2013",
"format": "eot",
"weight": "normal",
"style": "normal",
"isGoogleFont": false,
"isAdobeFont": false,
"isCustomFont": true,
"isSystemFont": false
}
],
"fontFamiliesInCss": [
"Julius Sans One",
"Libre Baskerville",
"sans-serif",
"verdemoderna"
],
"googleFontsUrls": [
"http://fonts.googleapis.com/css?family=Julius+Sans+One%7CLibre+Baskerville:400,400italic"
],
"adobeKitIds": [],
"stylesheetUrls": [
"https://csszengarden.com/214/214.css?v=8may2013"
]
}

The row is complete and shown with two-space JSON indentation. Empty arrays are valid when a page does not expose that source.

Source URLs and formats depend on what the public page exposes in its HTML and CSS.

💳 Pricing

Font Detector uses pay-per-event pricing. The charged event covers one public web page that is successfully analyzed and saved to the dataset. The event rate depends on your Apify usage tier, so see the Pricing tab for current rates.

Charged event

EventDescription
Font analysisOne public web page successfully analyzed and saved to the dataset.

🔌 Integrations

Use the Apify API, datasets, schedules, webhooks, and exports to move page analyses into your workflow.

❓ FAQ

Can it find a font from an image?

No. It reads public page HTML and linked CSS. It does not identify fonts from screenshots or image files.

What if a site adds fonts with JavaScript?

Fonts injected only after scripts run may not appear because the analysis uses public HTML and linked CSS.

What does one output row represent?

Each row represents one successfully analyzed public page. finalUrl records the public page URL reached after redirects.

What does partial mean?

The page was analyzed, but one or more linked stylesheets could not be read. The row can still include the available font data and a degradedReason.

Will every CSS family be a loaded font?

No. CSS family declarations can include fallback and system families. Use loadedFontCount, fonts.isSystemFont, and fontFamiliesInCss to compare detected entries with declared values.

Can it find Google Fonts references?

Yes. googleFontsUrls and Google font entries can show references exposed by the page or its readable stylesheets.

Can it show Adobe kit IDs?

It can record Adobe kit IDs when a public page or readable stylesheet exposes them.

Can it analyze pages that require a login?

No. Submit public pages that can be opened without credentials.

What does leaving maxPages empty do?

It returns all available results until the source is exhausted. When set, maxPages limits submitted targets for that run.

Can I use this as a website font checker API?

Yes. Run the Actor through the Apify API, pass targets, and read the dataset items when the run finishes.

📝 Changelog

v1.1 (04-10-2026)

  • Find font evidence in imported CSS and inline page styles.
  • Failed targets get one warning that names the submitted value and says processing continues. Skipped targets have no saved row or analyzed-page charge.
  • When the page limit is empty, analyze the full submitted list.
  • Save one analysis when several targets lead to the same page.

v1.0 (30-09-2026)

  • Saved page analyses now have one matching analyzed-page charge.
  • Progress logs show pages saved so far when the final eligible total is not known.

v0.1

  • Initial release.

🆘 Support

For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡

Made with ❤️ by Maxime Dupré