# Cross-origin isolation

Wavedash runs games cross-origin isolated. Every server your game talks to must send two response headers.

Source: https://docs.wavedash.com/platform/cross-origin-isolation

Wavedash serves your game in a [cross-origin-isolated](https://developer.mozilla.org/en-US/docs/Web/API/Window/crossOriginIsolated) context. Browsers gate several capabilities behind it:

- **`SharedArrayBuffer` and WebAssembly threads.** Multithreaded builds from Unity, Godot, and any Emscripten project compiled with pthreads depend on this. It also lets an engine run the game loop off the main thread so input stays responsive, and share lock-free buffers with an `AudioWorklet` for glitch-free audio.
- **High-resolution timers.** `performance.now()` resolves to 5 µs instead of 100 µs in Chrome, which tightens frame timing and profiling.
- **Memory measurement.** `performance.measureUserAgentSpecificMemory()` reports your page's real memory use in Chrome, so you can watch for leaks over long sessions.

To get there, every response from the game frame carries:

```http
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
```

Files inside your build are same-origin and need nothing. The catch is `require-corp`: the browser refuses to load any **cross-origin** response unless that response explicitly opts in. That includes your own backend API, asset CDNs, and font hosts.

## Required headers

Every server your game talks to must send both headers on every response, including error responses:

```http
Cross-Origin-Resource-Policy: cross-origin
Access-Control-Allow-Origin: *
```

`Access-Control-Allow-Origin` covers `fetch()` and XHR. `Cross-Origin-Resource-Policy` covers everything loaded without CORS: `<img>`, `<script>`, `<audio>`, `<video>`, fonts, and `mode: "no-cors"` fetches. Sending both means you never have to think about which one a given request needs.

<Warning>
If you send cookies (`credentials: "include"`), browsers reject `Access-Control-Allow-Origin: *`. Echo the request's `Origin` header back instead and add `Access-Control-Allow-Credentials: true`. The game's origin is a subdomain of `builds.wavedashcdn.com`, so validate that the host ends with `.builds.wavedashcdn.com`.
</Warning>

## Diagnosing a blocked request

A blocked request shows up in Chrome's console as:

```
net::ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep
```

`wavedash dev` serves the same cross-origin isolation headers as production, so blocked requests reproduce locally before you publish. `window.crossOriginIsolated` is `true` in both environments.

## What else is affected

- **WebSockets** are unaffected by cross-origin isolation.
- **Third-party iframes** (YouTube embeds, for example) must themselves be served with `Cross-Origin-Embedder-Policy: require-corp` and `Cross-Origin-Resource-Policy: cross-origin`. Most aren't, so they won't load inside the game frame.
- **`Wavedash.loadScript()`** and plain `<script src>` tags need `Cross-Origin-Resource-Policy: cross-origin` from the script's host.
- **Verifying player identity on your backend** works as usual once your responses carry the headers above. See [Players](/sdk/players#verifying-the-jwt-on-your-backend).
