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;
}
.contentkit-webframe-container {
@apply relative;
}
.contentkit-webframe-loading {
@apply absolute inset-0 m-auto size-5 animate-spin;
}
/** Card */
.contentkit-card {
@apply flex flex-col border rounded border-tint-subtle;
@@ -152,7 +152,7 @@ export function ElementWebframe(props: ContentKitClientElementProps<ContentKitWe
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
setMounted(true);
@@ -186,27 +186,27 @@ export function ElementWebframe(props: ContentKitClientElementProps<ContentKitWe
? iframeRef.current.clientWidth / height
: undefined);
if (!mounted) {
return <Icon icon="spinner" className="contentkit-button-loading" style={{ height }} />;
}
// only use height measurement if no aspect ratio is defined
const useHeightMeasurement = !aspectRatio && height;
return (
<iframe
ref={iframeRef}
src={element.source.url}
title={element.source.url}
allowFullScreen
allow="clipboard-write"
className="contentkit-webframe h-full w-full max-w-full border-none"
style={{
aspectRatio,
height: useHeightMeasurement ? height : undefined,
maxHeight: height,
}}
/>
<div className="contentkit-webframe-container h-full w-full max-w-full">
<iframe
ref={iframeRef}
// Rendered without a source before mount so it reserves its size in the SSR layout.
src={mounted ? element.source.url : undefined}
title={element.source.url}
allowFullScreen
allow="clipboard-write"
className="contentkit-webframe block h-full w-full max-w-full border-none"
style={{
aspectRatio,
height: useHeightMeasurement ? height : undefined,
maxHeight: height,
}}
/>
{mounted ? null : <Icon icon="spinner" className="contentkit-webframe-loading" />}
</div>
);
}