CORS for CDN and Static Assets

Configure CORS headers for serving fonts, images, and scripts from a CDN. Covers S3, CloudFront, Cloudflare, and common issues with font loading.

Common Issues

Detailed Explanation

Why CDN Assets Need CORS

When a web page at https://app.example.com loads a font from https://cdn.example.com, the browser treats this as a cross-origin request. Without CORS headers, the font will be blocked (particularly by Firefox), causing FOUT (Flash of Unstyled Text) or missing glyphs.

Resources That Require CORS

Resource CORS Required?
Fonts (@font-face) Yes — always cross-origin blocked
Images in <canvas> YesdrawImage taints the canvas
JavaScript modules Yes<script type="module"> uses CORS
Regular <script> No — loaded in "no-cors" mode
Regular <img> No — unless read via canvas
CSS stylesheets No — unless using fetch()

AWS S3 + CloudFront

S3 bucket CORS configuration:

[
  {
    "AllowedHeaders": ["*"],
    "AllowedMethods": ["GET", "HEAD"],
    "AllowedOrigins": ["*"],
    "ExposeHeaders": ["Content-Length", "Content-Type", "ETag"],
    "MaxAgeSeconds": 86400
  }
]

CloudFront: Add Origin to the Origin Request Policy and Access-Control-Allow-Origin to the Response Headers Policy.

Cloudflare

Cloudflare Workers can add CORS headers:

addEventListener("fetch", (event) => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);
  const newHeaders = new Headers(response.headers);
  newHeaders.set("Access-Control-Allow-Origin", "*");
  newHeaders.set("Access-Control-Max-Age", "86400");
  return new Response(response.body, { ...response, headers: newHeaders });
}

Nginx for Static Files

location ~* \.(woff2?|ttf|eot|otf|svg|png|jpg|webp)$ {
    add_header Access-Control-Allow-Origin "*" always;
    add_header Access-Control-Max-Age 86400 always;
    add_header Cache-Control "public, max-age=31536000, immutable";
}

Font-Specific Tip

If fonts load in Chrome but not Firefox, it is almost certainly a CORS issue. Firefox is stricter about enforcing CORS for @font-face resources.

Use Case

A web application loads custom web fonts from a CDN subdomain. Fonts render correctly in Chrome but are missing in Firefox. The fix is adding Access-Control-Allow-Origin: * to the CDN's response headers for font files.

Try It — CORS Header Builder

Open full tool