Vue & Nuxt

Vue & Nuxt

Because the LookIA widget is a standard JavaScript snippet, it integrates seamlessly with both Vue 3 (Vite-based SPAs) and Nuxt applications. The recommended approach depends on whether your project is an SPA or server-rendered.

Vue 3 (Vite SPA)

Editing index.html

For a plain Vue 3 + Vite project, add the script tag to the index.html file in the project root:

<!-- index.html -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Vue App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
    <!-- LookIA Widget -->
    <script
      src="https://cdn.lookia.io/lookia-widget.min.js"
      data-site-id="YOUR-UNIQUE-SITE-ID"
      defer
    ></script>
  </body>
</html>

Using a Vue Plugin

For a more idiomatic approach, create a Vue plugin to load the script programmatically on app mount:

// src/plugins/lookia.ts
import type { App } from 'vue'

export default {
  install(_app: App) {
    if (typeof document === 'undefined') return

    const script = document.createElement('script')
    script.src = 'https://cdn.lookia.io/lookia-widget.min.js'
    script.setAttribute('data-site-id', 'YOUR-UNIQUE-SITE-ID')
    script.defer = true
    document.body.appendChild(script)
  },
}

Then register it in src/main.ts:

// src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import LookIAPlugin from './plugins/lookia'

createApp(App).use(LookIAPlugin).mount('#app')

Nuxt (Recommended Approach)

Using useHead in the Root Layout

In a Nuxt application, use the useHead composable inside your root app.vue to inject the script. Nuxt handles SSR safety automatically.

<!-- app.vue -->
<script setup lang="ts">
useHead({
  script: [
    {
      src: 'https://cdn.lookia.io/lookia-widget.min.js',
      'data-site-id': 'YOUR-UNIQUE-SITE-ID',
      defer: true,
      tagPosition: 'bodyClose',
    },
  ],
})
</script>

<template>
  <NuxtPage />
</template>

Using a Nuxt Plugin

For better separation of concerns, create a client-only Nuxt plugin:

// plugins/lookia.client.ts
export default defineNuxtPlugin(() => {
  const script = document.createElement('script')
  script.src = 'https://cdn.lookia.io/lookia-widget.min.js'
  script.setAttribute('data-site-id', 'YOUR-UNIQUE-SITE-ID')
  script.defer = true
  document.body.appendChild(script)
})

The .client.ts suffix ensures the plugin only runs in the browser, preventing server-side rendering errors when accessing document.

Using nuxt.config.ts

You can also declare the script globally in nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        {
          src: 'https://cdn.lookia.io/lookia-widget.min.js',
          'data-site-id': 'YOUR-UNIQUE-SITE-ID',
          defer: true,
          tagPosition: 'bodyClose',
        },
      ],
    },
  },
})

Opening the Widget Programmatically in Vue

You can trigger the LookIA modal from any Vue component using a composable wrapper:

// composables/useLookIA.ts
export function useLookIA() {
  const open = () => {
    if (typeof window !== 'undefined' && window.LookIA) {
      window.LookIA.open()
    }
  }

  const close = () => {
    if (typeof window !== 'undefined' && window.LookIA) {
      window.LookIA.close()
    }
  }

  return { open, close }
}

Then use it inside any component:

<!-- components/SearchButton.vue -->
<script setup lang="ts">
const { open } = useLookIA()
</script>

<template>
  <button @click="open" aria-label="Open search">
    Search
  </button>
</template>

For TypeScript support, declare the global Window type extension in a file like types/global.d.ts:

export {}
declare global {
  interface Window {
    LookIA?: { open: () => void; close: () => void }
  }
}

Verifying the Integration

  1. Start your development server (npm run dev or pnpm dev).
  2. Open your app in the browser.
  3. The LookIA floating search button should appear in the bottom-right corner.
  4. Check the browser console for any script loading errors.