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.
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.
- 1.
R. Levien, "The 'font' Top-Level Media Type," RFC 8081, IETF, February 2017. https://www.rfc-editor.org/rfc/rfc8081
- 2.
W3C, "WOFF 2.0 - Web Open Font Format 2.0," w3.org, August 2024. https://www.w3.org/TR/WOFF2/
- 3.
"Can I use... WOFF 2.0," caniuse.com, accessed June 2026. https://caniuse.com/woff2
- 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.
Google, "Google Fonts Troubleshooting," developers.google.com, accessed June 2026. https://developers.google.com/fonts/docs/troubleshooting
- 6.
W3C, "CSS Fonts Module Level 4," w3.org, February 2022. https://www.w3.org/TR/css-fonts-4/
- 7.
"fontTools Subset Documentation," fonttools.readthedocs.io, accessed June 2026. https://fonttools.readthedocs.io/en/stable/subset/index.html
- 8.
"Fontsource," fontsource.org, accessed June 2026. https://fontsource.org/