diff --git a/components/blocksSubtemplates/buttonRow.tsx b/components/blocksSubtemplates/buttonRow.tsx index 81e57047e0..8df05d6387 100644 --- a/components/blocksSubtemplates/buttonRow.tsx +++ b/components/blocksSubtemplates/buttonRow.tsx @@ -8,7 +8,16 @@ import React, { useCallback, useRef, useState } from "react"; import { useResizeObserver } from "usehooks-ts"; import { Button } from "../button/templateButton"; +// Outer guard: bail out before any hooks when there's nothing to render, so the +// 13-of-14 button rows on a page that carry no buttons don't create a +// ResizeObserver or read layout. All layout-measuring hooks live in the inner +// component, which only mounts when buttons exist. const ButtonRow = ({ className, data }) => { + if (!(data.buttons?.length > 0)) return null; + return ; +}; + +const ButtonRowInner = ({ className, data }) => { const buttonContainer = useRef(null); const buttonRefs = useRef([]); const [buttonIsFullWidth, setButtonIsFullWidth] = useState(false); @@ -51,72 +60,68 @@ const ButtonRow = ({ className, data }) => { useResizeObserver({ ref: buttonContainer, onResize: measure }); return ( - <> - {data.buttons?.length > 0 && ( - - {data.buttons?.map((button, index) => { - const buttonElement = ( - { - buttonRefs.current[index] = node; - return () => { - if (fullWidthButtonIndex.current === index) { - fullWidthButtonIndex.current = null; - } - delete buttonRefs.current[index]; - }; - }} - className={cn( - "text-base font-semibold", - index !== fullWidthButtonIndex.current && - buttonIsFullWidth && - "w-full sm:w-auto" - )} - key={`image-text-button-${index}`} - data={button} - /> - ); + + {data.buttons?.map((button, index) => { + const buttonElement = ( + { + buttonRefs.current[index] = node; + return () => { + if (fullWidthButtonIndex.current === index) { + fullWidthButtonIndex.current = null; + } + delete buttonRefs.current[index]; + }; + }} + className={cn( + "text-base font-semibold", + index !== fullWidthButtonIndex.current && + buttonIsFullWidth && + "w-full sm:w-auto" + )} + key={`image-text-button-${index}`} + data={button} + /> + ); - const isInPageAnchor = button.buttonLink?.startsWith("#"); + const isInPageAnchor = button.buttonLink?.startsWith("#"); - return button.buttonLink && !button.leadCaptureFormOption ? ( - isInPageAnchor ? ( - { - e.preventDefault(); - const target = document.getElementById( - button.buttonLink.slice(1) - ); - target?.scrollIntoView({ behavior: "smooth" }); - history.replaceState(null, "", button.buttonLink); - }} - > - {buttonElement} - - ) : ( - - {buttonElement} - - ) - ) : ( - - {buttonElement} - - ); - })} - - )} - > + return button.buttonLink && !button.leadCaptureFormOption ? ( + isInPageAnchor ? ( + { + e.preventDefault(); + const target = document.getElementById( + button.buttonLink.slice(1) + ); + target?.scrollIntoView({ behavior: "smooth" }); + history.replaceState(null, "", button.buttonLink); + }} + > + {buttonElement} + + ) : ( + + {buttonElement} + + ) + ) : ( + + {buttonElement} + + ); + })} + ); };