React / Next.js integration#
Use the ideal.house browser SDK directly in React or Next.js. There is no separate ideal.house React npm package in this guide.
Verification status: The SDK markup was checked against the current Dashboard template; React and Next.js official lifecycle/script documentation was reviewed on September 7, 2026. No customer application or production credentials were available, so validate the built application end to end.
Before loading the SDK: Open Dashboard → Settings, add your storefront origin to Allowed Origins (CORS), and click Save. Include the published hostname and any preview or staging origins you use; separate multiple origins with commas. See configuration steps.
Prerequisites and boundaries#
Prepare Shop ID, Publishable Key, an imported catalog SKU, and a client-rendered product/variant value. The Publishable Key may be present in browser markup. Keep Client Secrets, AI API keys, and any private product-import credentials on the server.
The SDK discovers DOM containers. React owns when those nodes are mounted; your integration owns resolving the current variant and replacing the container when its SKU changes.
Minimal SDK contract#
<script
src="https://sdk.ideal.house/sdk.js"
data-shop-id="<SHOP_ID>"
data-publishable-key="<PUBLISHABLE_KEY>"
async
></script>
<div data-idealhouse-button-container data-product-code="CHAIR-OAK-01"></div>
data-product-code must equal ideal.house catalog sku exactly.
React component#
Mount a fresh container whenever the product code changes. A key forces React to replace the DOM node instead of reusing a container that the SDK may already have populated:
type RoomVisualizerButtonProps = {
productCode?: string | null;
};
export function RoomVisualizerButton({ productCode }: RoomVisualizerButtonProps) {
const code = productCode?.trim();
if (!code) return null;
return (
<div
key={code}
data-idealhouse-button-container
data-product-code={code}
/>
);
}
Pass the selected variant SKU, not a product title, route slug, database ID, or option label. If selection is incomplete, render null.
Next.js App Router loader#
Place the SDK once in the narrowest shared layout that covers product pages. Next.js documents afterInteractive for scripts that load after some hydration:
import Script from 'next/script';
export function IdealhouseSdk() {
return (
<Script
id="idealhouse-room-visualizer-sdk"
src="https://sdk.ideal.house/sdk.js"
strategy="afterInteractive"
data-shop-id={process.env.NEXT_PUBLIC_IDEALHOUSE_SHOP_ID}
data-publishable-key={process.env.NEXT_PUBLIC_IDEALHOUSE_PUBLISHABLE_KEY}
/>
);
}
Render IdealhouseSdk once from a layout, then render RoomVisualizerButton inside a Client Component that owns variant selection. Values prefixed NEXT_PUBLIC_ are shipped to the browser; use them only for Shop ID and Publishable Key.
For the Pages Router or plain React, create the script once in the HTML shell, or use a single top-level effect:
useEffect(() => {
if (document.querySelector('script[src="https://sdk.ideal.house/sdk.js"]')) return;
const script = document.createElement('script');
script.src = 'https://sdk.ideal.house/sdk.js';
script.async = true;
script.dataset.shopId = '<SHOP_ID>';
script.dataset.publishableKey = '<PUBLISHABLE_KEY>';
document.head.append(script);
}, []);
React Strict Mode intentionally performs an extra development setup cycle, so the duplicate check is required. Do not remove the shared SDK tag when an individual product component unmounts.
Navigation, lists, and variants#
Client-side route changes do not reload the layout script. Key each product control by stable route identity plus SKU if the same SKU can appear in several simultaneously mounted views. For grids, every card needs its own SKU. When infinite scroll adds cards, React naturally mounts new clean containers.
For variant selection, derive selectedVariant.sku from your commerce state and pass it as productCode. Do not call an undocumented SDK refresh method. Quick-view drawers and route transitions should unmount their previous component so processed DOM does not leak into the next product.
If React hydration reports a mismatch, ensure the server and first client render agree. It is valid to render no container until client commerce state has resolved the SKU.
Import product data#
Map the commerce backend's canonical variant SKU to ideal.house sku. Use Product upload, then consult import products, job status, list products, update products, delete product, and errors and retries.
Any backend catalog query, webhook, scheduled sync, or launch-token service remains application code; the browser SDK does not provide it.
Verify and remove#
Test server render/hydration, a hard load, client navigation, browser Back/Forward, variant changes, null/unknown SKUs, repeated cards, quick view, Suspense/loading states, mobile, consent controls, and a production build. Confirm one SDK request and exact DOM Product Code/SKU equality. Inspect built client bundles for accidental secrets.
To remove, delete the shared SDK component/tag and all RoomVisualizerButton usages, remove the two public environment variables, build again, and verify no SDK URL or data-idealhouse-* markup remains.