Sometimes you may need to access a running sandbox application and preview the content in real time in a front-end client. This is useful for example to instantly preview React code generated by a codegen AI agent.

You can do this via a preview URL that routes to a specific port on your sandbox (e.g. port 3000 for npm run dev). This preview URL can be either public (does not require you to be authenticated to access it) or private (see down below).

They will look something like this:

https://tkmu0oj2bf6iuoag6mmlt8.preview.bl.run

Setting a custom domain on the preview URL is a feature coming soon!

Current limitations of real-time previews

JavaScript module bundlers handle real-time previewing. Here are the key compatibility requirements and limitations:

  • Module bundler must implement ping-pong
  • Webpack has been tested and works
  • Turbopack currently doesnโ€™t work as it doesnโ€™t support ping-pong (see issue raised to Vercel)
  • Blaxel has a 15-minute connection timeout. To maintain previews beyond this limit, ensure your bundler implements automatic reconnection

Private preview URLs

When you create a private preview URL a token is required to access the URL. You must include the token as:

Manage preview URLs

Blaxel console

You can create a preview URL for a sandbox from the Blaxel Console, on the overview of a sandbox:

Blaxel SDK

Create and manage a sandboxโ€™s public preview URL:


import { SandboxInstance } from "@blaxel/core";

const sandbox = await SandboxInstance.get("my-sandbox")

/// Create a public preview
try {
    await sandbox.previews.create({
        metadata: {
            name: "preview-test-1"
        },
        spec: {
            port: 443,
            public: true
        }
    })
    const previews = await sandbox.previews.list()
    if (previews.length < 1) {
        throw new Error("No previews found");
    }
    const preview = await sandbox.previews.get("preview-test-1")
    if (preview.name !== "preview-test-1") {
        throw new Error("Preview name is not correct");
    }
    const url = preview.spec?.url
    if (!url) {
        throw new Error("Preview URL is not correct");
    }
    const response = await fetch(`${url}/health`)
    if (response.status !== 200) {
        throw new Error("Preview is not working");
    }
    console.log("Preview is healthy :)")
} catch (e) {
    console.log("ERROR IN PREVIEWS NOT EXPECTED => ", e.error);
}

Or create a private preview:


import { SandboxInstance } from "@blaxel/core";

const sandbox = await SandboxInstance.get("my-sandbox")

/// Create a private preview
try {
    const preview = await sandbox.previews.create({
      metadata: {
        name: "preview-test-private"
      },
      spec: {
        port: 443,
        public: false
      }
    })
    const url = preview.spec?.url
    if (!url) {
      throw new Error("Preview URL is not correct");
    }
    const retrievedPreview = await sandbox.previews.get("preview-test-private")
    console.log(`Retrieved preview => url = ${retrievedPreview.spec?.url}`)
    const token = await preview.tokens.create(new Date(Date.now() + 1000 * 60 * 10)) // 10 minutes expiration
    console.log("Token created => ", token.value)
    const tokens = await preview.tokens.list()
    if (tokens.length < 1) {
      throw new Error("No tokens found");
    }
    if (!tokens.find((t) => t.value === token.value)) {
      throw new Error("Token not found in list");
    }
    console.log("Token created => ", token.value)
    const response = await fetch(`${url}/health`)
    if (response.status !== 401) {
      throw new Error(`Preview is not protected by token, response => ${response.status}`);
    }

    const responseWithToken = await fetch(`${url}/health?bl_preview_token=${token.value}`)
    if (responseWithToken.status !== 200) {
      throw new Error(`Preview is not working with token, response => ${responseWithToken.status}`);
    }
    console.log("Preview is healthy with token :)")
    await preview.tokens.delete(token.value)
} catch (e) {
  console.log("ERROR IN PREVIEWS NOT EXPECTED => ", e);
} 

Create if not exists

Just like for sandboxes, this helper function either retrieves an existing preview or creates a new one if it doesnโ€™t exist. Blaxel first checks for an existing preview with the provided name and either retrieves it or creates a new one using your specified configuration.


const sandbox = await SandboxInstance.get("my-sandbox")

const preview = await sandbox.previews.createIfNotExists({
      metadata: {
        name: "preview-name"
      },
      spec: {
        port: 443,
        public: false
      }
    })