From 893384a19d915029364754652ed2f18afa58665e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 18 Mar 2026 13:05:54 +0000 Subject: [PATCH] fix: load survey script directly via src instead of blob URL Fixes FORMBRICKS-TQ The blob URL approach was being blocked by CSP which doesn't include 'blob:' in script-src directive. Simplified to load script directly via src attribute: - Works with existing CSP ('self' is allowed) - No need for fetch, blob URLs, or eval - Properly executes and initializes window.formbricksSurveys - Adds cache-busting in development for fresh script loads --- .../modules/ui/components/survey/index.tsx | 32 +++++++------------ 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/apps/web/modules/ui/components/survey/index.tsx b/apps/web/modules/ui/components/survey/index.tsx index d23e9ec495..2212e38380 100644 --- a/apps/web/modules/ui/components/survey/index.tsx +++ b/apps/web/modules/ui/components/survey/index.tsx @@ -40,34 +40,24 @@ export const SurveyInline = (props: Omit) = isLoadingScript = true; try { const scriptUrl = props.appUrl ? `${props.appUrl}/js/surveys.umd.cjs` : "/js/surveys.umd.cjs"; - const response = await fetch( - scriptUrl, - process.env.NODE_ENV === "development" ? { cache: "no-store" } : {} - ); - if (!response.ok) { - throw new Error("Failed to load the surveys package"); - } - - const scriptContent = await response.text(); - - // Create a blob URL from the script content and load it via script src - // This ensures the script executes properly and initializes window.formbricksSurveys - const blob = new Blob([scriptContent], { type: "application/javascript" }); - const blobUrl = URL.createObjectURL(blob); - - // Wait for the script to load before proceeding + // Load the script directly via src to ensure proper execution + // This approach works with CSP and doesn't require blob URLs or eval await new Promise((resolve, reject) => { const scriptElement = document.createElement("script"); - scriptElement.src = blobUrl; + scriptElement.src = scriptUrl; + scriptElement.type = "text/javascript"; + + // Add cache-busting in development to ensure fresh script loads + if (process.env.NODE_ENV === "development") { + scriptElement.src += `?t=${Date.now()}`; + } + scriptElement.onload = () => { - // Clean up the blob URL after script loads - URL.revokeObjectURL(blobUrl); resolve(); }; scriptElement.onerror = () => { - URL.revokeObjectURL(blobUrl); - reject(new Error("Failed to execute the surveys script")); + reject(new Error("Failed to load the surveys package")); }; document.head.appendChild(scriptElement);