Skip to main content
Supported on
Snapchat

Capabilities and restrictions

Snapchat serves a Web Lens from its zip through a private URL scheme. Every file comes with a strict Content Security Policy and a permissions policy. Together they decide what your code can load, connect to, and access. This page describes them at a high level, so you can design around them rather than meet them in review.

These policies describe the current implementation and can change. Snap is confirming them before public release, and this page updates if they do.

Everything ships in the zip​

The policy allows resources from the Lens itself and nothing else. No external scripts, style sheets, fonts, images, audio, or video. If your game needs it, it goes in the zip.

The same applies to data. fetch() and XMLHttpRequest reach files inside the zip only, and the policy blocks WebSocket and WebRTC connections. A Web Lens can't call a web API, load remote configuration, send analytics, or talk to a game server. Design it to work fully offline. You reach Snapchat features such as leaderboards, Bitmoji, and persistent storage through the Web Lens API rather than the network.

What you can use​

  • Inline scripts and styles. Bundler output with inline code works as-is.
  • eval() and new Function(). Engines and bundlers that rely on them work.
  • WebAssembly, including streaming compilation. The page is cross-origin isolated, so SharedArrayBuffer and multi-threaded WebAssembly are available too.
  • Web Workers, loaded from a file in the zip or from a blob: URL.
  • Images from data: and blob: URLs, so textures you generate on a canvas at runtime work.
  • Fonts bundled in the zip or embedded as data: URLs.
  • Vibration, where the browser supports it. Nothing in the policy restricts navigator.vibrate, but only Android's webview implements it. See Haptics.

What's blocked​

  • Camera and microphone. A Web Lens is a full-screen web app; it doesn't receive the camera feed.
  • Motion sensors. The accelerometer, gyroscope, and magnetometer are off, so tilt controls aren't possible. Design for pointer input.
  • Geolocation, payments, USB, and MIDI.
  • Network access, including WebRTC.
  • Frames. The Lens can't embed an <iframe>, and nothing can embed the Lens.
  • Form submission. Forms can't send data anywhere.
  • The <base> element and web app manifests. Bundlers don't emit them by default; if yours does, turn that off.
  • Plugins and <object> or <embed> content.
  • Persistent browser storage. localStorage and IndexedDB work within a session but reset when the Lens closes, as Runtime environment explains. To keep data between launches, use storage from the Web Lens API.

File types​

Snapchat picks each file's media type from its extension. These extensions get the correct type:

KindExtensions
HTML.html, .htm
JavaScript.js, .mjs
CSS.css
JSON.json
WebAssembly.wasm
Images.png, .jpg, .jpeg, .gif, .webp, .svg
Audio.mp3
Video.mp4
Fonts.ttf, .otf, .woff, .woff2
Binary.bin, .data

Snapchat serves anything else as a generic binary stream, with media-type sniffing off. Two consequences:

  • Scripts must end in .js or .mjs, and style sheets in .css, or the browser refuses to run them. This matters most for ES modules.
  • Other assets, such as .glb models or .ktx2 textures, load fine through fetch(). Your code decides how to read them. Prefer .mp3 and .mp4 for audio and video played through HTML elements.

Reserved paths​

Paths beginning with /__snap/ belong to the platform. Don't place files there in your zip.

Was this page helpful?
Yes
No