From 86fa4eda28cc24343ca95e87394a0d44da6da2a1 Mon Sep 17 00:00:00 2001 From: Fizza-Mukhtar Date: Fri, 6 Mar 2026 08:51:39 -0800 Subject: [PATCH 1/2] fix(sandbox): auto-bypass CSB trust interstitial and guard preload script race (#3087) --- .../project/[id]/_components/canvas/frame/view.tsx | 7 +++++++ .../src/components/store/editor/sandbox/index.ts | 10 +++++++--- .../client/src/server/api/routers/project/project.ts | 11 ++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/apps/web/client/src/app/project/[id]/_components/canvas/frame/view.tsx b/apps/web/client/src/app/project/[id]/_components/canvas/frame/view.tsx index 1bb9434d06..8609f201d4 100644 --- a/apps/web/client/src/app/project/[id]/_components/canvas/frame/view.tsx +++ b/apps/web/client/src/app/project/[id]/_components/canvas/frame/view.tsx @@ -4,6 +4,7 @@ import type { IframeHTMLAttributes } from 'react'; import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { connect, WindowMessenger } from 'penpal'; +import { PreloadScriptState } from '@/components/store/editor/sandbox'; import type { Frame } from '@onlook/models'; import type { @@ -86,6 +87,12 @@ export const FrameComponent = observer( const setupPenpalConnection = () => { try { + const sandbox = editorEngine.activeSandbox; + if (sandbox?.preloadScriptState === PreloadScriptState.LOADING) { + console.log(`${PENPAL_PARENT_CHANNEL} (${frame.id}) - Preload script still loading, will retry on next load`); + return; + } + if (!iframeRef.current?.contentWindow) { console.error(`${PENPAL_PARENT_CHANNEL} (${frame.id}) - No iframe found`); onConnectionFailed(); diff --git a/apps/web/client/src/components/store/editor/sandbox/index.ts b/apps/web/client/src/components/store/editor/sandbox/index.ts index 258eacaf37..815e0324b4 100644 --- a/apps/web/client/src/components/store/editor/sandbox/index.ts +++ b/apps/web/client/src/components/store/editor/sandbox/index.ts @@ -110,9 +110,13 @@ export class SandboxManager { this.preloadScriptState = PreloadScriptState.INJECTED } catch (error) { console.error('[SandboxManager] Failed to ensure preload script exists:', error); - // Mark as injected to prevent blocking frames indefinitely - // Frames will handle the missing preload script gracefully - this.preloadScriptState = PreloadScriptState.NOT_INJECTED + this.preloadScriptState = PreloadScriptState.NOT_INJECTED; + setTimeout(() => { + if (this.preloadScriptState === PreloadScriptState.NOT_INJECTED) { + console.log('[SandboxManager] Retrying preload script injection...'); + void this.ensurePreloadScriptExists(); + } + }, 3000); } } diff --git a/apps/web/client/src/server/api/routers/project/project.ts b/apps/web/client/src/server/api/routers/project/project.ts index bfece724ee..91604a716b 100644 --- a/apps/web/client/src/server/api/routers/project/project.ts +++ b/apps/web/client/src/server/api/routers/project/project.ts @@ -84,15 +84,16 @@ export const projectRouter = createTRPCRouter({ const url = getSandboxPreviewUrl(branch.sandboxId, port); const app = new FirecrawlApp({ apiKey: env.FIRECRAWL_API_KEY }); - // Optional: Add actions to click the button for CSB free tier - // const _csbFreeActions = [{ - // type: 'click', - // selector: '#btn-answer-yes', - // }]; + const csbFreeActions = [{ + type: 'click', + selector: '#btn-answer-yes', + }]; + const result = await app.scrapeUrl(url, { formats: ['screenshot'], onlyMainContent: true, timeout: 10000, + actions: csbFreeActions, }); if (!result.success) { From cfc5c93bcb635cdb745efa633169e78e92b74900 Mon Sep 17 00:00:00 2001 From: Fizza-Mukhtar Date: Fri, 6 Mar 2026 09:10:30 -0800 Subject: [PATCH 2/2] fix: clear preload retry timeout on sandbox cleanup --- .../components/store/editor/sandbox/index.ts | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/web/client/src/components/store/editor/sandbox/index.ts b/apps/web/client/src/components/store/editor/sandbox/index.ts index 815e0324b4..5de79e56e5 100644 --- a/apps/web/client/src/components/store/editor/sandbox/index.ts +++ b/apps/web/client/src/components/store/editor/sandbox/index.ts @@ -22,6 +22,7 @@ export class SandboxManager { readonly gitManager: GitManager; private providerReactionDisposer?: () => void; private sync: CodeProviderSync | null = null; + private preloadRetryTimeoutId?: ReturnType; preloadScriptState: PreloadScriptState = PreloadScriptState.NOT_INJECTED routerConfig: RouterConfig | null = null; @@ -111,7 +112,7 @@ export class SandboxManager { } catch (error) { console.error('[SandboxManager] Failed to ensure preload script exists:', error); this.preloadScriptState = PreloadScriptState.NOT_INJECTED; - setTimeout(() => { + this.preloadRetryTimeoutId = setTimeout(() => { if (this.preloadScriptState === PreloadScriptState.NOT_INJECTED) { console.log('[SandboxManager] Retrying preload script injection...'); void this.ensurePreloadScriptExists(); @@ -218,11 +219,14 @@ export class SandboxManager { } clear() { - this.providerReactionDisposer?.(); - this.providerReactionDisposer = undefined; - this.sync?.release(); - this.sync = null; - this.preloadScriptState = PreloadScriptState.NOT_INJECTED - this.session.clear(); + if (this.preloadRetryTimeoutId) { + clearTimeout(this.preloadRetryTimeoutId); + this.preloadRetryTimeoutId = undefined; + } + this.providerReactionDisposer = undefined; + this.sync?.release(); + this.sync = null; + this.preloadScriptState = PreloadScriptState.NOT_INJECTED + this.session.clear(); } }