Docs

Configure CORS

Allow browser uploads and video playback from your application.

CORS determines whether a browser lets your website make cross-origin requests and read responses from your storage and CDN. It does not grant storage credentials or make files public. With customer-owned storage, configure it for each browser action you use: direct video uploads, playback, or both. A working storage connection does not prove either action works in a browser.

Identify the browser origins

List the origins where people upload or watch your videos. An origin includes the scheme, hostname, and port if one is present, but no path: for example, https://app.example.com or http://localhost:3000.

Include https://chunkify.dev if you upload or play videos in the Chunkify dashboard. Add your production, staging, and local application origins as needed. Test each origin separately; success in the dashboard does not establish that your website can use the same files.

Allow browser uploads

The Chunkify uploader sends a video directly from the browser to the selected storage with PUT and a Content-Type header. Allow that method and header from every origin that hosts the uploader. The browser may send an OPTIONS preflight first; for S3-style bucket policies, the provider handles that request using the configured PUT rule. Do not add OPTIONS to AllowedMethods.

For multipart sessions, also expose the storage response's ETag header. A multipart-capable uploader needs the exact ETag from each successful part PUT to complete the upload. Add ETag to ExposeHeaders even when the bucket is used only for uploads.

This bucket rule is needed only for browser uploads to customer-owned storage. Creating a source from an existing object or a video URL does not upload a file from the browser. The upload completion endpoint has its own CORS handling; its settings do not replace bucket CORS.

Allow video playback

When video files are served from another origin, allow the viewing website to request the HLS playlists, media segments, poster, timeline previews, and captions. Allow GET and HEAD, and permit the Range request header for players that request part of a media file. Expose Accept-Ranges, Content-Length, Content-Range, and ETag so browser code can inspect those responses when needed.

The browser needs these CORS headers on the response from the playback URL, usually your CDN domain. With an R2 custom domain, the bucket's CORS policy supplies them. With a separate CDN such as CloudFront, the CDN can pass through the bucket's CORS headers or add them itself. Test the CDN URL from the viewing website; a working bucket request does not prove playback works through the CDN.

Apply a merged bucket policy

Read your bucket's current CORS policy before changing it. S3-style CORS updates replace the complete policy, so include any rules your other applications still need. This example uses the AWS S3 API and CLI shape and combines upload and playback access for the Chunkify dashboard and one website. Uploads use PUT and Content-Type; multipart uploads also need the exposed ETag. Playback uses GET, HEAD, Range, and the exposed response headers:

{
  "CORSRules": [
    {
      "AllowedOrigins": ["https://chunkify.dev", "https://app.example.com"],
      "AllowedMethods": ["GET", "HEAD", "PUT"],
      "AllowedHeaders": ["Content-Type", "Range"],
      "ExposeHeaders": ["Accept-Ranges", "Content-Length", "Content-Range", "ETag"],
      "MaxAgeSeconds": 3600
    }
  ]
}

Replace the example origins with yours and merge this rule with the existing policy. If you do not use browser uploads, omit PUT and Content-Type. If uploads and playback happen on different websites, use separate rules so viewing-only origins are not allowed to make cross-origin PUT requests. The AWS S3 console accepts the CORSRules array without its outer object. Other providers may use a different format or console fields; apply the equivalent rule using their CORS settings. See the Amazon S3 and Cloudflare R2 CORS documentation for provider syntax.

Check the CDN edge

Confirm that the CDN returns CORS headers for your website's origin and supports the requests your player makes, including byte-range requests. It should preserve media Content-Type and range response headers. Check its cache rules too: a video asset's master playlist can change while processing continues.

Test from each website

From each application origin, upload a small video if you use browser uploads, then play a video asset through its CDN URL. Check the poster and timeline previews as well as the stream. In browser developer tools, inspect failed preflight and media requests for the request origin, method, headers, and the response's CORS headers. A successful server-side upload or direct download does not verify browser access.