Hosts
All ports on sandboxes are exposed on URLs following this pattern:
- HTTP/HTTPS:
https://$SANDBOX_ID-$PORT.csb.app
- WebSocket:
ws://$SANDBOX_ID-$PORT.csb.app
For example, if your sandbox ID is abc123
and your dev server runs on port 3000
, it would be accessible at https://abc123-3000.csb.app
.
Private Sandboxes
When you have private
Sandboxes the hosts can not be accessed by default. You will need to generate a token to access the hosts. You create signed urls to your Sandboxes using the hosts
API on the server:
const hostToken = await sdk.hosts.createToken('sandbox-id')
This gives you low level management of your Sandboxes hosts. You can pass the host token when connecting to the Sandbox, either on the server or in one of the clients. This is useful as any generated urls from the SDK will include the token:
const sandbox = await sdk.sandboxes.create({
id: 'some-template-id'
})
const hostToken = await sdk.hosts.createToken(sandbox.id)
// Signed URL
const url = sdk.hosts.getUrl(hostToken, 5173)
// Or create a session for the browser/node clients
const session = await sandbox.createSession({
hostToken
})
// In the browser you will get signed URLs
const url = client.hosts.getUrl(5173)
When you open a signed URL in the browser, we will automatically put the preview token in a cookie so subsequent requests from the same browser don't require the token.
Token expiration
You can set an expiration on the preview token when creating it:
const hostToken = await sdk.hosts.createToken('sandbox-id', {
expiresAt: new Date(Date.now() + 60 * 60 * 1000) // 1 hour
})
This is useful if you want to limit the lifetime of a host token. For example when a user shared a preview of their app with someone who should only have access for a limited time.
Proxying To Hosts
You can implement custom domains and routing by proxying requests through your own server. This allows you to create user-friendly URLs that map to your sandbox hosts while maintaining control over access and lifecycle management.
Use Cases
Implementing custom domains and proxy setups provides several benefits:
Better URLs
Transform technical sandbox URLs into user-friendly branded domains:
https://abc123-3000.csb.app
→https://my-project.yourdomain.com
- Improves user experience and branding
Security Note: We recommend evaluating using subdomains on a different domain than your main application. This mitigates blacklisting your domain due to phishing attempts.
Enhanced Security
- Token Protection: Hide preview tokens from end users by mapping app user sessions to preview tokens on your backend
- Access Control: Implement custom authentication and authorization logic
- Session Management: Control who can access previews and for how long
Custom Error Pages
Handle sandbox errors gracefully with branded error pages:
- Display custom 404 pages when sandboxes are not found
- Show maintenance pages during sandbox startup
- Provide helpful error messages for connection issues
Lifecycle Management
Implement intelligent sandbox management:
- Auto-Resume: Automatically wake up hibernated sandboxes on first request
- Auto-Hibernate: Put unused sandboxes to sleep to save resources
- Request-Based Control: Resume sandboxes only when needed (e.g., HTML requests but not asset requests)
Proxy Solutions
You can use various proxy solutions to implement custom domain routing:
- Nginx - Popular reverse proxy with excellent performance and configuration flexibility
- Cloudflare - CDN with built-in proxy capabilities and additional security features
- Vercel - Edge functions and serverless proxy solutions
- Custom Node.js/Express - Full control with custom middleware and logic
Performance Consideration: Using a proxy will increase latency as requests must travel through your proxy server before reaching CodeSandbox hosts.
Required Configuration
When proxying requests to CodeSandbox hosts, you must set the trust_csb_preview
cookie to ensure proper authentication:
// Set the csb_is_trusted cookie when proxying
res.cookie('csb_is_trusted', 'true', {
domain: '.csb.app',
httpOnly: true,
secure: true,
sameSite: 'none'
});
Example Implementation
For a complete example of implementing custom domain proxying with Nginx, see our example custom preview proxy repository (opens in a new tab).
Here is an example using Node:
import http from "http";
import httpProxy from "http-proxy";
import { CodeSandbox } from "@codesandbox/sdk";
const SOURCE_DOMAIN = "some-domain.com";
const TARGET_DOMAIN = "csb.app";
const TARGET_PROTOCOL = "https";
const PORT = process.env.PORT || 8080;
const sdk = new CodeSandbox();
const proxy = httpProxy.createProxyServer({});
const server = http.createServer(async (req, res) => {
const host = req.headers.host || "";
const suffix = `.${SOURCE_DOMAIN}`;
const subdomain = host.slice(0, -suffix.length); // e.g. "abc123-5173"
const m = subdomain.match(/^(.+)-(\d{1,5})$/);
const sandboxId = m[1];
const targetHost = `${subdomain}.${TARGET_DOMAIN}`;
const target = `${TARGET_PROTOCOL}://${targetHost}`;
const isHtmlRequest = accepts.includes("text/html");
if (isHtmlRequest) {
await sdk.sandboxes.resume(sandboxId);
}
const sanitizedCookies = (req.headers.cookie || "").split(";").map((c) => c.trim())
sanitizedCookies.push("csb_is_trusted=true");
const cookieHeader = sanitizedCookies.join("; ");
proxy.web(req, res, {
target,
changeOrigin: true,
secure: true,
headers: {
"X-Forwarded-Host": host,
cookie: cookieHeader,
},
});
});
This approach can be extended with:
- User session tracking - Know exactly which sandboxes belong to which users
- Automatic hibernation - Enforce hibernation when user sessions end
- Transparent access - Users can access their sandbox by mapping a friendly project name to a related sandboxId and port
⚡ Best practices
- Use private sandboxes - Set privacy 'private'` for secure sandbox hosts
- Persist host tokens - Persist one host token per sandbox alongside other sandbox metadata
- Proxy through your server - Route preview requests through your backend for lifecycle management and custom logic