On a headless storefront the widget is the same single script, but where you mount it matters so you don’t fight SSR or hydration. The pattern is consistent: render a placeholder, load the script lazily, keep it in a leaf component.
Next.js (App Router)
import Script from "next/script"
export function IdukkiGallery({ id }: { id: string }) {
return (
<div data-idukki-collection={id}>
<Script src="https://cdn.idukki.io/widget.js" strategy="lazyOnload" />
</div>
)
}Hydrogen, Astro and Remix
Use the same approach: place the placeholder div and the script in a leaf component, and load the script after hydration. In Hydrogen, a client-only wrapper avoids an SSR mismatch; in Astro, a client directive on the island does the same; in Remix, mount it in a component that only runs on the client.