Skip to content

Preview URLs: WebSocket support + CORS headers for cross-origin iframe previews #101

Description

@shtefcs

Problem

When embedding Upstash Box preview URLs in an iframe (common for AI coding agent platforms), two issues arise:

1. WebSocket not supported

Preview URLs (*.preview.box.upstash.com) don't support WebSocket connections. Next.js dev server uses WebSocket for Hot Module Replacement (HMR). Without it, HMR doesn't work and the browser console fills with connection errors:

WebSocket connection to 'wss://xxx-3000.preview.box.upstash.com/_next/webpack-hmr' failed

2. Empty CORS headers break font loading

Preview URL responses include access-control-allow-origin: (empty value, not *). In browsers, this causes 403 errors for resources loaded with the crossorigin attribute (fonts preloaded by Next.js):

GET https://xxx-3000.preview.box.upstash.com/__nextjs_font/geist-latin.woff2 403 (Forbidden)

Server-side fetch returns 200 — the issue is specifically that the empty CORS header causes browser rejection.

3. IntersectionObserver doesn't work in cross-origin iframes

This is a browser security restriction (W3C spec), not an Upstash bug. But it means scroll-triggered animations (framer-motion whileInView, GSAP ScrollTrigger, etc.) never fire when the preview is in a cross-origin iframe.

Feature request: Would it be possible to support custom preview domains (e.g., preview.automatio.ai) so the iframe can be same-origin with the host application? This would resolve the IntersectionObserver limitation.

Environment

  • @upstash/box: 0.1.28
  • Runtime: node
  • Use case: AI coding agent preview panel (iframe embedding)

Steps to Reproduce

  1. Create a box and start a Next.js dev server
  2. Get preview URL via box.getPreviewUrl(3000)
  3. Embed the preview URL in an iframe on a different origin
  4. Observe: WebSocket errors, font 403, IntersectionObserver always returns isIntersecting: false

Expected Behavior

  • WebSocket connections through preview URLs should work (for HMR)
  • CORS headers should be access-control-allow-origin: * (not empty)
  • Ideally: custom preview domains to enable same-origin iframe embedding

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions