Vue / Nuxt integration#
Use the ideal.house browser SDK directly in Vue or Nuxt and keep its generated-button container synchronized with reactive product state. There is no ideal.house Vue npm package in this guide.
Verification status: The SDK markup was checked against the current Dashboard template; Vue and Nuxt official documentation was reviewed on September 7, 2026. No customer application or production credentials were available.
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 SKU, and a reactive selected-variant record. Shop ID and Publishable Key may be client-visible. Keep Client Secrets, AI API keys, and product-import credentials on the server.
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>
The Product Code must equal the catalog sku exactly.
Vue component#
Give the container a key so Vue creates a clean node when the selected SKU changes:
<script setup lang="ts">
import { computed } from 'vue'
const props = defineProps<{ productCode?: string | null }>()
const code = computed(() => props.productCode?.trim() || '')
</script>
<template>
<div
v-if="code"
:key="code"
data-idealhouse-button-container
:data-product-code="code"
/>
</template>
Pass the canonical selected variant SKU. Render nothing for an incomplete selection instead of leaving the prior code visible.
Nuxt loader#
Nuxt's useHead supports external script tags. Register it once in app.vue or a layout that covers product pages:
<script setup lang="ts">
const config = useRuntimeConfig()
useHead({
script: [
{
key: 'idealhouse-room-visualizer-sdk',
src: 'https://sdk.ideal.house/sdk.js',
async: true,
'data-shop-id': config.public.idealhouseShopId,
'data-publishable-key': config.public.idealhousePublishableKey,
},
],
})
</script>
Configure only public values under runtimeConfig.public. For plain Vue, add the script once to the application HTML or create it in the root component's onMounted() with a querySelector duplicate check. Browser DOM APIs must run client-side.
Variants and dynamic navigation#
Bind selectedVariant.sku to the component. The keyed node handles option changes without an undocumented SDK method. When Nuxt route data changes while the component instance is reused, the computed code updates and the old container is destroyed.
For product grids, every card needs an item-level SKU and stable Vue key. Infinite scroll and filters should render new components from state; never copy DOM that the SDK already populated. Quick-view drawers should unmount on close, and a new product should receive a new component key.
If SSR and hydration do not know the same SKU, render no button until client product state is ready, or serialize the canonical SKU in the page payload. Avoid reading a SKU only from rendered option text.
Import product data#
Map each commerce variant's canonical SKU to ideal.house sku. Use Product upload and the guides for import products, job status, list products, update products, delete product, and errors and retries.
Your backend commerce client, webhooks, scheduled sync, and private credentials stay outside the browser SDK.
Verify and remove#
Test SSR/hydration, hard reload, client navigation, browser Back/Forward, every variant, blank/unknown SKUs, repeated cards, quick view, <KeepAlive>, loading states, mobile, consent, and a production build. Confirm exactly one SDK request and exact DOM Product Code/SKU equality. Inspect built assets for secrets.
To remove, delete the useHead/root loader and all button components, remove public runtime configuration, rebuild, and verify the SDK URL and data-idealhouse-* markup are absent.