Skip to content

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

@shtefcs

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions