Render an application in real-time via a direct preview URL for its running sandbox.
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:
Copy
Ask AI
https://tkmu0oj2bf6iuoag6mmlt8.preview.bl.run
Setting a custom domain on the preview URL is a feature coming soon!
The Blaxel SDK authenticates with your workspace using credentials from these sources, in priority order:
when running on Blaxel, authentication is handled automatically
variables in your .env file (BL_WORKSPACE and BL_API_KEY, or see this page for other authentication options).
environment variables from your machine
configuration file created locally when you log in through Blaxel CLI (or deploy on Blaxel)
When developing locally, the recommended method is to just log in to your workspace with Blaxel CLI. This allows you to run Blaxel SDK functions that will automatically connect to your workspace without additional setup. When you deploy on Blaxel, this connection persists automatically.
When running Blaxel SDK from a remote server that is not Blaxel-hosted, we recommend using environment variables as described in the third option above.
Create and manage a sandboxโs public preview URL:
Copy
Ask AI
import { SandboxInstance } from "@blaxel/core";const sandbox = await SandboxInstance.get("my-sandbox")/// Create a public previewtry { 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:
Copy
Ask AI
import { SandboxInstance } from "@blaxel/core";const sandbox = await SandboxInstance.get("my-sandbox")/// Create a private previewtry { 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);}
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.