Hi
Has anyone experienced something similar
Btw it's a custom RichText field
i've also tried using useMemo within my embed component to prevent unnecessary re-renders of the embed itself
The rendered embedded url glitches when you scroll on the site
const reconstructEmbedUrl = (originalUrlString) => {
if (!originalUrlString) {
return originalUrlString;
}
try {
const tempUrl = new URL(originalUrlString);
const hostname = tempUrl.hostname.toLowerCase();
const pathname = tempUrl.pathname;
if (hostname.includes('youtube.com') || hostname.includes('youtu.be')) {
let videoId = null;
if (hostname.includes('youtu.be')) {
videoId = pathname.substring(1);
} else if (pathname.includes('/watch')) {
videoId = tempUrl.searchParams.get('v');
} else if (pathname.includes('/embed/')) {
videoId = pathname.split('/embed/')[1]?.split('/')[0];
}
if (videoId) {
const embedUrl = new URL(`https://www.youtube.com/embed/${videoId}`);
embedUrl.searchParams.set('rel', '0');
if (tempUrl.searchParams.has('t')) {
embedUrl.searchParams.set(
'start',
tempUrl.searchParams.get('t').replace('s', ''),
);
}
return embedUrl.toString();
}
}
if (hostname.includes('vimeo.com')) {
const pathParts = pathname.split('/');
const videoId = pathParts.pop() || pathParts.pop();
if (videoId && /^\d+$/.test(videoId)) {
if (
hostname.includes('player.vimeo.com') &&
pathname.includes('/video/')
) {
return originalUrlString;
}
return `https://player.vimeo.com/video/${videoId}`;
}
}
} catch (e) {
return originalUrlString;
}
return originalUrlString;
};
embed: ({node}) => {
const {url, customHeight, isDatawrapper, oembedHtml} = React.useMemo(() => {
let processedUrl = null;
let height = null;
let datawrapper = false;
let htmlContent = node.oembed?.html || null;
try {
const initialEmbedUrlString = node.oembed?.embed_url;
if (
!initialEmbedUrlString ||
typeof initialEmbedUrlString !== 'string' ||
initialEmbedUrlString.trim() === ''
) {
return {
url: processedUrl,
customHeight: height,
isDatawrapper: datawrapper,
oembedHtml: htmlContent,
};
}
const reconstructedEmbedUrlString = reconstructEmbedUrl(
initialEmbedUrlString,
);
processedUrl = new URL(reconstructedEmbedUrlString);
height = processedUrl.searchParams.get('height');
if (height) {
processedUrl.searchParams.delete('height');
}
if (node.oembed) {
datawrapper =
(node.oembed.provider_name &&
node.oembed.provider_name
.toLowerCase()
.includes('datawrapper')) ||
(node.oembed.provider_url &&
node.oembed.provider_url.includes('datawrapper')) ||
(initialEmbedUrlString &&
(initialEmbedUrlString.includes('datawrapper.dwcdn.net') ||
initialEmbedUrlString.includes('datawrapper.de')));
}
} catch (error) {
console.error(
'Error processing embed URL:',
node.oembed?.embed_url,
error,
);
return {
url: null,
customHeight: null,
isDatawrapper: false,
oembedHtml: htmlContent,
};
}
return {
url: processedUrl,
customHeight: height,
isDatawrapper: datawrapper,
oembedHtml: htmlContent,
};
}, [
node.oembed?.embed_url,
node.oembed?.html,
node.oembed?.provider_name,
node.oembed?.provider_url,
]);
if (!node.oembed) {
console.error('Missing oembed data for node, returning null:', node);
return null;
}
if (oembedHtml) {
let divStyleHeight = undefined;
if (!isDatawrapper) {
if (node.oembed.height) {
divStyleHeight = `${node.oembed.height}px`;
} else if (customHeight) {
divStyleHeight = `${customHeight}px`;
} else {
divStyleHeight = '400px';
}
}
return (
<div
className={`${styles.iframe} ${!isDatawrapper ? styles.default : ''}`}
style={{
height: divStyleHeight,
position: 'relative',
width: '100%',
}}
dangerouslySetInnerHTML={{__html: oembedHtml}}
/>
);
}
if (!url) {
console.log('Embed URL is not available, cannot render iframe.');
return null;
}
return (
<div
className={styles.iframe}
style={{
height: customHeight ? `${customHeight}px` : undefined,
position: 'relative',
width: '100%',
}}
>
<iframe
style={{
position: !customHeight ? 'absolute' : undefined,
top: !customHeight ? 0 : undefined,
left: !customHeight ? 0 : undefined,
width: '100% !important',
height: customHeight
? `${customHeight}px`
: !customHeight
? '100%'
: 230,
}}
src={url.toString()}
title={node.oembed.title || 'Embedded content'}
data-oembed={node.oembed.embed_url}
data-oembed-type={node.oembed.type}
data-oembed-provider={node.oembed.provider_name}
frameBorder='0'
allowFullScreen
loading='lazy'
/>
</div>
);
},