> ## Documentation Index
> Fetch the complete documentation index at: https://docs.timothe.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Nuxt への組み込み

> Nuxt 3, 4 のサイトに Turnint AI の埋め込みスクリプトを組み込む 3 つのパターンと、コピペで動く example repository の使い方

Nuxt 3, 4 で構築されたサイトに Turnint AI の埋め込みスクリプトを組み込む方法をまとめます。`nuxt-module` の追加や独自の plugin / composable は基本的に不要で、`app.vue` でスクリプトを 1 度読み込めば、あとは `data-turnint-*` 属性または `window.turnintai.open()` で起動できます。

<Info>
  動作する完全なサンプルを公開しています。

  * example repo: [github.com/u17g/turnint-ai-nuxt-example](https://github.com/u17g/turnint-ai-nuxt-example)
  * preview: [example-turnint-ai-nuxt-japanese-lp.vercel.app](https://example-turnint-ai-nuxt-japanese-lp.vercel.app/)

  以下のコードはこの repo の `japanese-landing-page/` ディレクトリと一致しています。手元で動かしたい場合は repo を clone して `pnpm install && pnpm dev` で起動してください。
</Info>

## 3 つの組み込みパターン

| パターン            | 使いどころ                                     | 必要な実装                                       |
| --------------- | ----------------------------------------- | ------------------------------------------- |
| A. ボタンで開く       | LP の CTA、ヘッダーやフッターの「資料を見る」など、ユーザー操作で起動したい | `data-turnint-*` 属性を付けたボタン                  |
| B. ページ表示時に自動で開く | 専用ルート（例: `/start`）に着地したら即座に埋め込みを立ち上げたい    | `onMounted` で `window.turnintai.open()` を呼ぶ |
| C. インライン表示      | ページ内の特定領域に埋め込みをそのまま表示したい                  | `data-turnint-*` 属性を付けた `<div>`             |

いずれのパターンでも、共通の前提として **embed script をアプリ全体で 1 度だけ読み込む** 必要があります。次のセクションで設定します。

## 共通: embed script を読み込む

`app/app.vue`（Nuxt 4）または `app.vue`（Nuxt 3）で `useHead` を使い、Turnint AI の embed script を `<head>` に注入します。

```vue theme={null}
<script setup>
useHead({
  script: [
    {
      src: "https://cdn.turnint.ai/js/latest/turnint.ai.embed.js",
      async: true,
      "data-turnint-namespace": "ws_xxxxxxxxxxxxxxxx",
      "data-turnint-locale": "ja",
    },
  ],
})
</script>

<template>
  <div>
    <NuxtRouteAnnouncer />
    <NuxtPage />
  </div>
</template>
```

`async` を付けることで、初期描画をブロックせずにスクリプトを読み込めます。読み込みが完了すると `window.turnintai` が利用可能になり、以後すべてのページで起動 API が使えます。

<Note>
  スクリプトは `app.vue` で 1 度だけ読み込めば十分です。各ページで個別に `useHead` を呼ぶ必要はありません。
</Note>

## パターン A: ボタンクリックで開く

最もシンプルな方法です。任意の要素に `data-turnint-*` 属性を付与すると、その要素がクリックされたタイミングで埋め込みが開きます。

```vue theme={null}
<template>
  <button
    data-turnint-id="pub_xxxxxxxxxxxxxxxx"
    data-turnint-type="fullscreen"
  >
    AI と資料を読む
  </button>
</template>
```

| 属性                  | 値の例                      | 説明                                               |
| ------------------- | ------------------------ | ------------------------------------------------ |
| `data-turnint-id`   | `pub_xxxxxxxxxxxxxxxx`   | 開きたいコンテンツの ID。ダッシュボードから取得                        |
| `data-turnint-type` | `fullscreen` / `popover` | 開き方。`fullscreen` は画面全体を覆うモーダル、`popover` はチャットバブル |

埋め込みの UI 言語は embed script 側の `data-turnint-locale` で指定します。複数のボタンやインライン埋め込みを同じページに置く場合も、script は 1 度だけ読み込めば十分です。

<Note>
  Nuxt の `<NuxtLink>` でページ遷移した後に新しく追加されたボタンも、自動で検知されて起動可能になります。route 変更ごとに手動で再マウントする必要はありません（詳しくは後述の「SPA ナビゲーションについて」を参照）。
</Note>

## パターン B: ページ表示時に自動で開く

「LP の CTA から専用ページに飛ばし、着地した瞬間に埋め込みを立ち上げたい」というユースケース向けのパターンです。専用の空白ページを 1 つ作り、`onMounted` 内で `window.turnintai.open()` を呼びます。

```vue theme={null}
<!-- app/pages/start.vue -->
<script setup lang="ts">
import { onMounted } from "vue"

type TurnintAI = {
  open(config: {
    id?: string
    type?: "fullscreen"
    locale?: "ja" | "en" | "auto"
    onClose?: () => void
  }): void
}
type WindowWithTurnintAI = Window & typeof globalThis & { turnintai?: TurnintAI }

onMounted(() => {
  const openWhenReady = () => {
    const w = window as WindowWithTurnintAI
    if (w.turnintai) {
      w.turnintai.open({
        id: "pub_xxxxxxxxxxxxxxxx",
      })
      return
    }
    requestAnimationFrame(openWhenReady)
  }
  openWhenReady()
})
</script>

<template>
  <section />
</template>
```

embed script は `async` で読み込んでいるため、`onMounted` の発火時点ではまだ `window.turnintai` が定義されていない可能性があります。`requestAnimationFrame` でフレームごとに再チェックすることで、ロード完了直後に確実に `open()` を呼び出せます。

<Note>
  `type: "fullscreen"` 以外の指定は現状サポートされていません。インライン表示が必要な場合はパターン C を使ってください。
</Note>

## パターン C: インライン表示

ページ内の特定領域に埋め込みを表示したい場合は、`<div>` などに `data-turnint-*` 属性を付けます。`data-turnint-type="inline"` を指定すると、その要素の中に埋め込みが描画されます。

```vue theme={null}
<template>
  <div
    data-turnint-id="pub_xxxxxxxxxxxxxxxx"
    data-turnint-type="inline"
    style="width: 100%;"
  />
</template>
```

要素の幅は CSS 側で確保してください（埋め込みは親要素のサイズに合わせて描画されます）。

## TypeScript で型を効かせる

`window.turnintai` の公式型定義はパッケージとしては配信していないため、プロジェクト側で型を宣言します。`types/turnintai.d.ts` のようなファイルを作成し、以下を貼り付けてください。

```ts theme={null}
// types/turnintai.d.ts
export {}

declare global {
  interface Window {
    turnintai?: {
      open: (config: {
        id?: string
        type?: "fullscreen"
        endpoint?: string
        locale?: "ja" | "en" | "auto"
        onClose?: () => void
      }) => void
    }
  }
}
```

Nuxt は `tsconfig.json` を自動生成するため、`types/` ディレクトリに置けば自動的に読み込まれます。明示的に取り込みたい場合は `nuxt.config.ts` の `typescript.tsConfig.include` に追加してください。

## 関連ドキュメント

* [クイックスタート](/ja/get-started/quickstart) — 共有方法と埋め込み方式の全体像
* [Google Tag Manager 経由で導入する](/ja/get-started/onboarding/google-tag-manager) — GTM のカスタム HTML タグで導入する手順
* [トラッキングパラメータの自動保持](/ja/integrations/tracking-params) — UTM などの引き継ぎ
