From e0ee1e3348279373ee4331d8d08fdaa3ab8ae490 Mon Sep 17 00:00:00 2001 From: tom Date: Tue, 11 Aug 2026 21:07:06 +0200 Subject: [PATCH] Don't feed the placeholder dapp URL to the marketplace iframe (#3581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `useAppQuery` serves a stub app as `placeholderData` while the real dapp is loading. Its `url` is `https://example.com`, which the dapp page passed straight into the iframe `src` — so the browser really fetched example.com and flashed it before the actual dapp URL arrived. The stub URL also broke `getAppUrl`: a legitimate `?url=` param was compared against the stub's origin and silently dropped as foreign. Skip the URL entirely while the query holds placeholder data, and keep the iframe unmounted (loader visible) until a real URL is available. The latter also covers the essential-dapp page, where the URL comes from config and can be undefined. Co-Authored-By: Claude Opus 5 --- src/features/marketplace/components/MarketplaceAppIframe.tsx | 4 ++-- src/features/marketplace/pages/dapp/MarketplaceApp.tsx | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/features/marketplace/components/MarketplaceAppIframe.tsx b/src/features/marketplace/components/MarketplaceAppIframe.tsx index ebbc7349df6..6a3b156312c 100644 --- a/src/features/marketplace/components/MarketplaceAppIframe.tsx +++ b/src/features/marketplace/components/MarketplaceAppIframe.tsx @@ -80,11 +80,11 @@ const Content = chakra(({ appUrl, address, message, isEssentialDapp, className } minW="100%" className={ className } > - { (isFrameLoading) && ( + { (isFrameLoading || !appUrl) && ( ) } - { isReady && ( + { isReady && appUrl && ( getAppUrl(data?.url, router), [ data?.url, router ]); + const appUrl = useMemo( + () => getAppUrl(isPlaceholderData ? undefined : data?.url, router), + [ data?.url, isPlaceholderData, router ], + ); const message = useMemo(() => ({ blockscoutColorMode: colorMode,