Reserve webframe size before hydration (#4683)

This commit is contained in:
Peter White
2026-10-14 08:25:57 +02:00
committed by GitHub
parent 03aa0f75f5
commit f7dc7faa65
3 changed files with 32 additions and 18 deletions
@@ -0,0 +1,6 @@
---
"@gitbook/react-contentkit": patch
"gitbook": patch
---
Reserve the webframe's size in the server-rendered layout so anchor links to content below integration blocks no longer land too high.
@@ -52,6 +52,14 @@
@apply relative; @apply relative;
} }
.contentkit-webframe-container {
@apply relative;
}
.contentkit-webframe-loading {
@apply absolute inset-0 m-auto size-5 animate-spin;
}
/** Card */ /** Card */
.contentkit-card { .contentkit-card {
@apply flex flex-col border rounded border-tint-subtle; @apply flex flex-col border rounded border-tint-subtle;
@@ -152,7 +152,7 @@ export function ElementWebframe(props: ContentKitClientElementProps<ContentKitWe
window.addEventListener('message', callback); window.addEventListener('message', callback);
// We only render the iframe once we have added the event listener // We only load the iframe once we have added the event listener
// otherwise during SSR, we'll miss messages // otherwise during SSR, we'll miss messages
setMounted(true); setMounted(true);
@@ -186,27 +186,27 @@ export function ElementWebframe(props: ContentKitClientElementProps<ContentKitWe
? iframeRef.current.clientWidth / height ? iframeRef.current.clientWidth / height
: undefined); : undefined);
if (!mounted) {
return <Icon icon="spinner" className="contentkit-button-loading" style={{ height }} />;
}
// only use height measurement if no aspect ratio is defined // only use height measurement if no aspect ratio is defined
const useHeightMeasurement = !aspectRatio && height; const useHeightMeasurement = !aspectRatio && height;
return ( return (
<iframe <div className="contentkit-webframe-container h-full w-full max-w-full">
ref={iframeRef} <iframe
src={element.source.url} ref={iframeRef}
title={element.source.url} // Rendered without a source before mount so it reserves its size in the SSR layout.
allowFullScreen src={mounted ? element.source.url : undefined}
allow="clipboard-write" title={element.source.url}
className="contentkit-webframe h-full w-full max-w-full border-none" allowFullScreen
style={{ allow="clipboard-write"
aspectRatio, className="contentkit-webframe block h-full w-full max-w-full border-none"
height: useHeightMeasurement ? height : undefined, style={{
maxHeight: height, aspectRatio,
}} height: useHeightMeasurement ? height : undefined,
/> maxHeight: height,
}}
/>
{mounted ? null : <Icon icon="spinner" className="contentkit-webframe-loading" />}
</div>
); );
} }