Sandbox Pages

Sandbox Pages

Sandbox Pages are special extension pages with a different set of CSP restrictions. For example, it is possible to eval arbitrary code inside a sandbox page. Use the sandbox page to dynamically run code in a secure context with more privileges compared to an extension page.

A sandbox page can mount UI components similar to a CSUI or execute simple scripts. The following example showcases the ability to eval arbitrary code from a sandbox page and communicate the result back to the caller via message passing.

First, we want to add a sandbox page:

  1. Create a sandbox.ts file or a sandboxes/<name>.ts file in the source directory (project root or src)
  2. Export the following script:
export const life = 42
window.addEventListener("message", async function (event) {
  const source = event.source as {
    window: WindowProxy
  source.window.postMessage(eval(, event.origin)

The script above listens to a message event from the window scope, and evals the code sent by the caller via the data property. The sandbox page is now available under sandbox.html OR sandboxes/<name>.html in the extension bundle. To send messages to this page, we will need to mount it inside an iframe, and invoke the postMessage API. Let's do so in a popup.tsx extension page:

import { useEffect, useRef, useState } from "react"
function IndexPopup() {
  const iframeRef = useRef<HTMLIFrameElement>(null)
  useEffect(() => {
    window.addEventListener("message", (event) => {
      console.log("EVAL output: " +
  }, [])
  return (
        display: "flex",
        flexDirection: "column",
        padding: 16
        onClick={() => {
          iframeRef.current.contentWindow.postMessage("10 + 20", "*")
        Trigger iframe eval
      <iframe src="sandbox.html" ref={iframeRef} style={{ display: "none" }} />
export default IndexPopup

When a user clicks the trigger iframe eval, they will see the result of the eval done inside the sandbox page.

See rfc-263 (opens in a new tab) for more details.