Web Font MIME Types: WOFF2, TTF, and CORS

Web font MIME types affect browser parsing and CORS enforcement. font/woff2 as the only modern format, cross-origin CORS rules, and CSS @font-face format hints.

Web Font MIME Types: WOFF2, TTF, CORS, and @font-face

Web font MIME types affect both browser parsing and CORS enforcement. The font/ top-level type was registered in RFC 8081, which also formalised font/woff2 (WOFF2), font/woff (WOFF 1.0), font/ttf (TrueType), and font/otf (OpenType).1 Among these, font/woff2 is the only format worth serving to modern browsers: it uses Brotli compression on a single stream containing every font table, achieving smaller file sizes than WOFF 1.0's zlib compression and universal support across all browsers released since 2016.2 Cross-origin font loading triggers CORS enforcement in every browser, making Access-Control-Allow-Origin a required header on any font server accessed from a different domain. The CSS @font-face rule's format() hint in the src descriptor controls which font file the browser fetches.

Font formats registered under RFC 8081

  • font/woff2 Brotli compression, universal support since 2016 — the only format worth serving
  • font/woff WOFF 1.0, zlib compression — needed only for IE 11
  • font/ttf, font/otf installation formats, not meant for HTTP delivery
  • Browser support since Chrome 36, Firefox 39, Safari 10, Edge 14

Opens the MIME Type Reference with this page's checklist shown at the top of the tool.

Open in the tool →

Why WOFF2 is the only format worth serving to modern browsers

WOFF2 applies Brotli compression to a single concatenated stream of all font tables, producing smaller font files than WOFF 1.0's zlib compression and far smaller files than uncompressed TTF or OTF.2 WOFF2 support reached all major browsers by 2016: Chrome 36, Firefox 39, Safari 10, and Edge 14 all support it.3 For any project targeting browsers from 2016 forward, WOFF2 is sufficient as the sole format in a @font-face declaration. TTF and OTF are installation formats designed for desktop operating systems, not for HTTP delivery. Serving them over the web delivers uncompressed font data many times larger than the equivalent WOFF2. Furthermore, adding TTF to a @font-face src as a fallback increases HTTP requests without providing usable fallback coverage, since any browser capable of loading @font-face supports WOFF2. The only justified exception is Internet Explorer 11, which requires WOFF.

Cross-origin font loading and CORS enforcement

Every browser enforces CORS for fonts loaded from a different origin. When a CSS @font-face rule references a font URL on a CDN or a different domain, the browser sends an Origin header with the font request. The font server must include Access-Control-Allow-Origin: * or the specific page origin in the response.4 Without this header, the browser drops the font request and the page renders with its CSS fallback font stack. Detecting the issue requires examining the font request in the browser Network panel and looking for a CORS-related error in the response details.

Google Fonts and CORS

Google Fonts serves font files from a CDN with Access-Control-Allow-Origin: * already configured, so pages that reference fonts.googleapis.com work without any additional CORS setup.5 Self-hosted fonts on a CDN subdomain require explicit CORS configuration because the browser treats the CDN origin as separate from the page origin. In Nginx, add add_header Access-Control-Allow-Origin "*" inside a location block matching font file extensions. In Cloudflare, configure a custom header rule to add Access-Control-Allow-Origin for font paths.

@font-face format hints in CSS

The format() function in the @font-face src descriptor tells the browser the format of each font file before downloading it, allowing the browser to skip formats it does not support. The value for WOFF2 is "woff2". For WOFF, use "woff". For TTF, use "truetype". For OTF, use "opentype".6 Browsers evaluate the src list from left to right and download the first format they support. Placing WOFF2 first ensures modern browsers use the most compressed format. For projects that require IE 11 compatibility, include WOFF as a second src entry after WOFF2.

Variable fonts

Variable fonts use font/woff2 as the MIME type regardless of whether they are variable, because the variable font capabilities are internal to the font file and do not affect the Content-Type header the server sends. A single variable WOFF2 file can replace dozens of static font files covering every weight and width variant, which dramatically reduces the number of HTTP requests and the total font payload for your page. The @font-face format hint "woff2" applies to both static and variable WOFF2 files.6 Some implementations use "woff2-variations" as a hint, but this is not required by the specification and regular "woff2" is sufficient.

Reducing WOFF2 file size through Unicode subsetting

Full-featured fonts include glyphs for hundreds of languages and thousands of characters. A Latin-only project serving a complete Unicode WOFF2 font downloads glyph data for scripts it never renders. Font subsetting extracts only the character ranges the project uses, producing a smaller WOFF2 file. Google Fonts has applied subsetting automatically for years: each @font-face block from the Google Fonts CSS API includes a unicode-range descriptor limiting the download to the characters declared in that block.

The pyftsubset tool from the Python fonttools library performs offline subsetting, letting you extract specific Unicode ranges from a full font file to produce a smaller WOFF2 that contains only the characters your project needs.7 The unicode-range descriptor in @font-face works alongside subsetting: the browser downloads only the subset files covering characters present on the rendered page, making multi-file subset strategies practical without increasing initial page load.

Self-hosting subsetted fonts with Fontsource

Fontsource packages pre-subsetted Google Fonts files as npm packages, with separate WOFF2 files per Unicode range and pre-written @font-face declarations included that your bundler can import directly.8 Installing a Fontsource package adds WOFF2 files and CSS to node_modules, giving you full control over font hosting without relying on a third-party CDN. Self-hosting via Fontsource eliminates the external DNS lookups for fonts.googleapis.com and fonts.gstatic.com while preserving the same subsetting approach Google Fonts applies, which means your pages load faster and work offline during development.

Self-hosting also removes a third-party failure point, because a CDN outage at fonts.googleapis.com no longer blocks your text rendering or triggers a flash of fallback fonts during the outage. Bundling the subsetted files with your application keeps font delivery inside your own deploy pipeline and your own cache policy, and setting font/woff2 for self-hosted fonts removes the MIME gap that lets CORS drop the request. CapyToolkit's MIME reference confirms font/woff2 as the correct Content-Type for the served subset files.

When to use this

Use this guide when configuring a web server to serve fonts correctly to all browsers, setting up font hosting on a CDN, or debugging silent font loading failures caused by CORS or MIME type issues.

Examples

CSS @font-face with WOFF2 only for modern browsers

A single WOFF2 entry is sufficient for all browsers released since 2016. No TTF or OTF fallback is needed.

Nginx: serve WOFF2 with correct MIME type and CORS header

Add font/woff2 to the types block and configure CORS for cross-origin font loading.

@font-face with WOFF fallback for IE 11

Add WOFF only if IE 11 support is required. Modern browsers always pick WOFF2 first.

Sources
  1. 1.

    R. Levien, "The 'font' Top-Level Media Type," RFC 8081, IETF, February 2017. https://www.rfc-editor.org/rfc/rfc8081

  2. 2.

    W3C, "WOFF 2.0 - Web Open Font Format 2.0," w3.org, August 2024. https://www.w3.org/TR/WOFF2/

  3. 3.

    "Can I use... WOFF 2.0," caniuse.com, accessed June 2026. https://caniuse.com/woff2

  4. 4.

    Mozilla Developer Network, "@font-face," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@font-face

  5. 5.

    Google, "Google Fonts Troubleshooting," developers.google.com, accessed June 2026. https://developers.google.com/fonts/docs/troubleshooting

  6. 6.

    W3C, "CSS Fonts Module Level 4," w3.org, February 2022. https://www.w3.org/TR/css-fonts-4/

  7. 7.

    "fontTools Subset Documentation," fonttools.readthedocs.io, accessed June 2026. https://fonttools.readthedocs.io/en/stable/subset/index.html

  8. 8.

    "Fontsource," fontsource.org, accessed June 2026. https://fontsource.org/

FAQ

Cross-origin font loading requires Access-Control-Allow-Origin from the CDN. Local development serves fonts from the same origin, bypassing CORS. The CDN must be configured to add this header for font files. Check the font request in the Network panel and look for a CORS error in the response details section rather than waiting for a visible error.

No. TTF and OTF are uncompressed installation formats not optimised for HTTP delivery. WOFF2 provides the same font data with Brotli compression, reducing file size substantially. Serving TTF or OTF as web fonts increases load time with no benefit for any browser that supports WOFF2, which is all browsers released since 2016.

font-display: swap tells the browser to display text using the fallback font immediately and swap to the web font when it loads. This prevents invisible text during font loading. The swap value is the recommended setting for most web font use cases and improves perceived performance and Core Web Vitals scores.

No. Google Fonts CDN already sends Access-Control-Allow-Origin: * on all font files. CORS configuration is only needed when you self-host fonts on a different domain or CDN from your application. If you host fonts on a CDN subdomain like fonts.yourdomain.com, configure Access-Control-Allow-Origin on that domain.

Yes. Variable fonts use font/woff2 as the MIME type. The variable font capabilities are defined inside the font file, not in the MIME type or format hint. Use format("woff2") in your @font-face src descriptor. Some documentation suggests format("woff2-variations") but the base "woff2" value is sufficient and broadly supported. CapyToolkit's MIME reference confirms font/woff2 as the standard type for both static and variable web fonts.

Additional resources