Skip to content

Assets and networking

A bundle is not limited to a single file. It can ship scripts, stylesheets, images, fonts, audio, and subfolders, and it can reach remote hosts when you ask for permission. This page explains how files load and what is allowed.

Multi-file bundles and relative paths

Your entry point can reference other files in the bundle with normal relative paths. All of these resolve as you would expect:

html
<link rel="stylesheet" href="./style.css" />
<script src="./lib/app.js"></script>
<img src="assets/bg.png" />

This works for scripts, stylesheets, images, media, fonts, web workers, and fetch or XMLHttpRequest calls to your own files. Subfolders are fine, including for the entry point itself:

jsonc
{ "name": "main", "entrypoint": "scenes/main.html", "type": "overlay" }

Your bundle's own files are always allowed. You never need a permission to load something that ships inside the bundle.

Fonts

A font file shipped inside the bundle loads through a normal relative path and needs no permission:

css
@font-face {
  font-family: 'MyFont';
  src: url('./fonts/myfont.woff2') format('woff2');
}

A font loaded from a remote host, such as Google Fonts, needs a network.font permission for each host involved. Google Fonts uses two:

jsonc
{ "scope": "network.font", "value": "https://fonts.googleapis.com/*", "reason": "Loads the font stylesheet" },
{ "scope": "network.font", "value": "https://fonts.gstatic.com/*",    "reason": "Loads the font files" }

Shipping the font inside the bundle is the simpler and more reliable choice when you can.

Remote network access

To reach any remote origin, request the matching network permission and list the host in value. Wildcards are supported, and you can list several entries.

NeedScope
fetch or XMLHttpRequest over HTTP(S)network.http
WebSocket connectionnetwork.ws
Remote web fontnetwork.font
jsonc
{ "scope": "network.http", "value": "https://api.example.com/*", "reason": "Fetches score data" },
{ "scope": "network.ws",   "value": "wss://*.example.com/*",     "reason": "Live updates" }

A request to a host you did not list is blocked. See Permissions for the full rules.

Media entry points

If a content entry's entrypoint is a media file rather than HTML, it is drawn directly as an image or video, the same as a plain media overlay. The SDK is not injected for media entry points, and there is no network or scripting surface for them. This is handy when you want to switch between an interactive surface and a static image or clip based on a condition. See the manifest reference.

What is allowed, in short

  • Your own files: always allowed, no permission needed. Use relative paths.
  • data: and blob: URLs: allowed, for inline assets and generated content.
  • Remote origins: allowed only when listed under a matching network.* permission.

If something does not load and it is a remote URL, the most likely cause is a missing network.* permission for that host.