contentsquare-web-tag-install について
Web プロジェクトへの Contentsquare トラッキングタグの導入と、ブラウザーでの検証を案内するスキルです。フレームワーク別の手順を示し、ウィザードのレポートでタグの読み込み、ページビュー、CSP の問題を確認します。
主な機能
- 01フレームワーク別の導入手順
- 02ブラウザー環境での初期化
- 03ウィザードによる実行時検証
- 04ページビューと CSP の確認
- 05検証失敗への対処案内
活用シーン
- 01Web アプリへの Contentsquare タグ追加
- 02タグの読み込みと遷移時のページビュー確認
- 03Contentsquare 関連の CSP 違反の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ contentsquare/ agents --skill contentsquare-web-tag-installインストール後、Claude Code で/contentsquare-web-tag-installを入力して読み込まれたか確認します。
詳細
Contentsquare タグをインストールする
Web プロジェクトへの Contentsquare トラッキングタグのインストールと検証を支援します。 このドキュメントを上から順に進めてください。セクションを飛ばさないでください。
実行時の検証は、1 つのコマンドですべて行います:
npx --yes @contentsquare/wizard@2 verify
このコマンドは実際のブラウザーを起動し、開発者がアプリ内をクリックして操作できるようにして、タグの読み込み、最初のページビュー、ページ遷移時のページビュー、CSP の問題を 1 つのセッションで報告します。これは必要に応じて npx によって解決されます(初回実行後はキャッシュされます)。グローバルにインストールするものはなく、ブラウザーをこちらで操作することもありません。@2 の固定指定によって現在のメジャー系列が追跡されるため、パッチやマイナーの修正を受け取りながら、検証の再現性も保たれます。--yes は、まだパッケージがキャッシュされていないマシンで非対話型エージェントの処理を妨げる、npx の初回実行時の「Ok to proceed?」インストール確認を省略します。
ルール(最初に読み、常に適用してください)
- パッケージ名は正確に
@contentsquare/tag-sdkです。関数名は正確にinjectContentsquareScriptです。必須のオプションはclientIdだけです。別のものに置き換えたり、名前を変更したり、 代替案を作り出したりしないでください。 injectContentsquareScriptはブラウザーのコンテキストでのみ実行する必要があります。SSR 中には決して実行しないでください。サーバーで実行されるファイル(Next.js Server Component、Nuxt server route、SvelteKit+page.server.tsなど)に配置する場合は、誤りです。- タグ ID(別名、ハッシュ化されたプロジェクト ID)は、小文字の 16 進文字列で、約 13 文字
(例:
81c677ba742d7)です。手元の値が通常の 10 進数、メールアドレス、URL、その他の値に見える場合は、そこで止めてハッシュ化されたプロジェクト ID を尋ねてください。ID を自分でハッシュ化、変換、生成、推測してはいけません。 - フレームワークの判定は、実際のコマンド出力だけを根拠にしてください。判定が曖昧な場合や
package.jsonが見つからない場合は、開発者に尋ねてください。 - 開発サーバーを起動、再起動、終了しないでください。必ず開発者に操作を依頼してください。
- CSP は、
verifyが違反を報告した場合、または既存の CSP に Contentsquare のドメインが含まれていないことが分かった場合にのみ変更してください。CSP ヘッダーが存在しないプロジェクトに、予防的に追加しないでください。 - パッケージマネージャーを確認し、プロジェクトのルートにいることを確認してから、
npm install(または同等のコマンド)を実行してください。 - 検証に 2 回失敗したら、コードの変更を止め、開発者に指示を仰いでください。
- プロジェクトに
tsconfig.jsonがない場合は、以下のファイルパスとテンプレートすべてで.ts/.tsxではなく.js/.jsx拡張子を使用してください。
完了条件 — 次のすべてが真の場合にのみ完了です(すべて verify の出力に基づきます):
tagScriptLoaded: true— タグスクリプトt.contentsquare.net/uxa/<tagId>.jsが読み込まれた。initialPageview: true—t.contentsquare.netへの追加リクエストが少なくとも 1 件送信された。cspViolations: []— Contentsquare のドメインに関する CSP 違反がない。
「コードが正しく見える」ことを根拠に成功を宣言しないでください。verify のレポートだけが判定基準です。
開始前 — タグ ID を取得する
- 開発者の最初の指示にタグ ID が記載されていないか確認します(例:「Contentsquare をインストール、タグ ID は
81c677ba742d7」)。記載されている場合は、その値をそのまま使用し、再度尋ねないでください。 - プロジェクトに
.cs-wizard/state.jsonがある場合は、そこからtagIdを読み取り、使用します。 - まだタグ ID が分からない場合は、次のように尋ねます:
"Contentsquare のタグ ID を教えてください。
clientIdとして使う 16 進文字列(例:81c677ba742d7)です。タグスニペットまたは Settings で確認できます。"
この値は --tag-id <tagId> として verify に渡します。
手順
- インストール — フレームワークを検出し、SDK をインストールして、初期化コードを追加します。
- 検証 —
npx @contentsquare/wizard verifyを 1 回実行します。開発者がアプリを操作します。 - CSP の修正 —
verifyがcspViolationsを報告した場合にのみ行います。 - 再検証 — すべてが問題ないことを確認するため、
verifyを再実行します。
ステップ 1 — タグをインストールする
1.1 フレームワークを特定する
プロジェクトを調べてください。推測してはいけません。
cat package.json | grep -E '"next"|"nuxt"|"vue"|"react"|"@angular/core"|"svelte"|"@sveltejs/kit"|"vite"|"@contentsquare/'
ls package-lock.json yarn.lock pnpm-lock.yaml bun.lockb 2>/dev/null
ls tsconfig.json 2>/dev/null
ls src/app app src/pages pages 2>/dev/null
ls src/main.ts src/main.tsx src/index.ts src/index.tsx app/layout.tsx app/layout.jsx src/app/layout.tsx src/app/layout.jsx pages/_app.tsx pages/_app.jsx 2>/dev/null
grep -r "contentsquare\|injectContentsquareScript\|_uxa" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" --include="*.html" -l 2>/dev/null | grep -v node_modules
以下を特定してください:
- フレームワーク(優先順位:Next.js > React、Nuxt > Vue、SvelteKit > Svelte、Angular、Vite)
- App Router または Pages Router(Next.js のみ) —
app/またはsrc/app/が存在するか確認します - TypeScript(tsconfig.json が存在する場合)または JavaScript
- パッケージマネージャー(npm/yarn/pnpm/bun)
- すでにインストール済みか → ステップ 2 に進みます
1.2 開発者に確認する
「[framework] を [TS/JS] で使用しており、[package manager] を使用していることを検出しました。エントリーポイントは
[file]です。正しいですか?」
確認が取れるまで先に進まないでください。タグ ID がまだ分からない場合は、ここで尋ねてください。
1.3 パッケージをインストールして初期化コードを追加する
npm install @contentsquare/tag-sdk
# or: yarn add / pnpm add / bun add — match the detected package manager
以下の <TAG_ID> を、開発者の実際のタグ ID に置き換えてください。
Next.js — App Router — layout があるパスにクライアントコンポーネントを作成します(app/contentsquare.tsx または src/app/contentsquare.tsx)。
'use client';
import { useEffect } from 'react';
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
export function Contentsquare() {
useEffect(() => {
injectContentsquareScript({ clientId: '<TAG_ID>' });
}, []);
return null;
}
次に、ルートレイアウト(同じディレクトリ)に <Contentsquare /> を追加します。
import { Contentsquare } from './contentsquare';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Contentsquare />
{children}
</body>
</html>
);
}
Next.js — Pages Router — pages/_app.tsx に追加します。
import { useEffect } from 'react';
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
injectContentsquareScript({ clientId: '<TAG_ID>' });
}, []);
return <Component {...pageProps} />;
}
React(Vite / CRA) — ReactDOM.createRoot の前に、src/main.tsx(または src/index.tsx)に追加します。
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
injectContentsquareScript({ clientId: '<TAG_ID>' });
Vue(Vite) — src/main.ts に追加します。
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
injectContentsquareScript({ clientId: '<TAG_ID>' });
Nuxt 3 — plugins/contentsquare.client.ts を作成します(.client サフィックスにより、ブラウザーでのみ実行されます)。
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
export default defineNuxtPlugin(() => {
injectContentsquareScript({ clientId: '<TAG_ID>' });
});
Angular — bootstrapApplication / platformBrowserDynamic().bootstrapModule(...) の前に、src/main.ts に追加します。
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
injectContentsquareScript({ clientId: '<TAG_ID>' });
SvelteKit — src/routes/+layout.svelte に追加します。
<script lang="ts">
import { onMount } from 'svelte';
import { injectContentsquareScript } from '@contentsquare/tag-sdk';
onMount(() => {
injectContentsquareScript({ clientId: '<TAG_ID>' });
});
</script>
<slot />
静的 HTML / サーバーサイドレンダリング(Django、Rails、Laravel、PHP、WordPress、または JavaScript フレームワークを使用しない場合)— <head> 内に追加します。
<script src="https://t.contentsquare.net/uxa/<TAG_ID>.js" defer></script>
一般的な配置場所:Django → templates/base.html、Rails → app/views/layouts/application.html.erb、Laravel → resources/views/layouts/app.blade.php、WordPress → header.php。
カスタム変数や仮想ページビューに
_uxaAPI を使用する場合は、スクリプトの読み込み前にコマンドをバッファリングできるよう、代わりに IIFE ローダーパターンを使用してください。
<script>
(function(c,s,q,u,a,r,e){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
e=s.createElement(q);e.async=1;e.src=u;
r=s.getElementsByTagName(q)[0];r.parentNode.insertBefore(e,r);
})(window,document,'script','https://t.contentsquare.net/uxa/<TAG_ID>.js','_uxa');
</script>
1.4 検証の準備をする
開発者に開発サーバーを起動するよう依頼してください。自分で起動してはいけません。その後、ステップ 2 に進みます。
ステップ 2 — ウィザード CLI で確認する
初回実行前に、.cs-wizard/ がプロジェクトの .gitignore に含まれていることを確認してください。検証ツールはここにレポート(last-report.json、last-browser-error.json)を書き込みます。これらはコミットしないでください。記載がなければ追加してください。
プロジェクトのルートから検証ツールを実行してください。プロンプトが表示されないように URL とタグ ID を渡し、標準出力に機械可読なレポートをそのまま出力するために --json を指定します(これがエージェントモードです)。
npx --yes @contentsquare/wizard@2 verify --url http://localhost:3000 --tag-id <TAG_ID> --json
フレームワークごとの URL のデフォルト値:Next.js / Nuxt / CRA → http://localhost:3000、
Vite → http://localhost:5173、Angular → http://localhost:4200。
このコマンドは対話形式で、開発者が作業を終えるまで処理をブロックします。 実際のブラウザーを開いて待機します。ハングしたと決めつけたり、キャンセルしたりタイムアウトさせたりしないでください。 フォアグラウンドで実行し、コマンドが自動的に終了するまで待ちます。
実行される内容:
- ページ上に Contentsquare のバナーが重なった状態で、指定 URL を開く実際のブラウザーウィンドウが表示されます。
- 開発者に次のように伝えてください:「ブラウザーが開きました。アプリを操作してください。最初のページが読み込まれるのを待ち、アプリ内のいくつかのルートをクリックして移動し、必要に応じてログインしてください。終わったら、バナーの Done をクリックするか、ウィンドウを閉じてください。」
- 開発者が Done をクリックするかウィンドウを閉じたときにのみ、コマンドが終了してレポートを出力します。
標準出力に出力された JSON、または .cs-wizard/last-report.json(毎回の実行で書き込まれます)から結果を読み取ってください。終了コード:
| コード | 意味 |
|---|---|
0 | pass または pass-with-recommendation |
1 | fail(レポートは実行されました)、または不明な理由でブラウザーの起動に失敗しました({"error":"BROWSER_LAUNCH_FAILED"}) |
2 | ブラウザーエンジンが見つかりません({"error":"NO_BROWSER"}) |
3 | ブラウザーはインストールされていますが、システムライブラリが不足しています({"error":"MISSING_LIBS"}) |
4 | ブラウザーはインストールされていますが、起動を拒否しました。例:エンタープライズポリシー、またはすでに使用中のプロファイル({"error":"BLOCKED_LAUNCH"}) |
5 | グラフィカルディスプレイがありません(ヘッドレス Linux マシン)。verify には表示可能なウィンドウが必要です({"error":"NO_DISPLAY"}) |
これらはいずれもクラッシュではなく、通常のレポートまたは環境上の結果として扱ってください。ブラウザー環境に関する失敗(2~5)では、--json モードは標準出力に {"error":"<CODE>"} オブジェクトを出力し、.cs-wizard/last-browser-error.json に記録を残し、標準エラー出力に対処方法を表示します。以下の ブラウザーを取得できない場合 を参照してください。
ブラウザーを取得できない場合
verify がコード 2~5 で終了した場合、使用可能なブラウザーを取得できませんでした。--json モードでは、stdout に {"error":"<CODE>"} が出力され、stderr には対応する対処方法が表示されます。コードに応じて対処してください。
| 終了コード/エラー | 意味 | 対処方法 |
|---|---|---|
2 NO_BROWSER | ブラウザーエンジンがインストールされていません。 | 開発者に許可を求めてから、--install-browser を指定して再実行します(以下を参照)。 |
3 MISSING_LIBS | ブラウザーはインストールされていますが、OS ライブラリが不足しています(最小構成の Linux でよく発生します)。ダウンロードしても解決しません。 | 開発者に sudo npx playwright-core install-deps chromium を実行してもらってから、ステップ 2 を再実行します。 |
4 BLOCKED_LAUNCH | ブラウザーはありますが、起動が拒否されました(企業ポリシー、または使用中のプロファイルが原因です)。 | 開発者に Chrome/Edge のウィンドウをすべて閉じてから再試行してもらいます。または、同梱のエンジンをインストールして --install-browser を指定し、再実行します。 |
5 NO_DISPLAY | ディスプレイのないヘッドレス Linux 環境で実行されています。verify には表示ウィンドウが必要です。 | 開発者はグラフィカルディスプレイのあるマシン(自身のデスクトップ)で verify を実行する必要があります。ヘッドレスでは実行できません。 |
NO_BROWSER(2)の場合は、開発者に許可を求めます。
「検証ツールにはブラウザーエンジンが必要ですが、見つかりませんでした。Chromium(約 150 MB)をダウンロードしてもよろしいですか(一度のみ)?」
はいの場合、インストールフラグを指定して再実行します。
npx --yes @contentsquare/wizard@2 verify --url <url> --tag-id <TAG_ID> --json --install-browser
企業プロキシの背後でダウンロードに失敗した場合、CLI に設定が必要なプロキシ環境変数(HTTPS_PROXY、NODE_EXTRA_CA_CERTS、PLAYWRIGHT_DOWNLOAD_HOST)が表示されます。それらを開発者に伝えてから再実行します。
レポートに応じた対処
| レポート | 対処 |
|---|---|
result: "pass" | 決定論的なチェック(タグの読み込み、最初のページビュー、CSP)は問題ありません。完了前に、以下のナビゲーショントラッキングも評価してください。 |
result: "pass-with-recommendation" | タグは機能していますが、CSP 違反が検出されました。recommendation をそのまま提示してから、ステップ 3 に進みます。以下のナビゲーショントラッキングも評価してください。 |
tagScriptLoaded: false | タグが読み込まれていません。injectContentsquareScript がクライアント側(useEffect/onMount/.client.ts)で実行され、パッケージがインストールされていることを確認します。ステップ 2 を再実行します。 |
initialPageview: false (script loaded) | タグ ID が正しく、プロジェクトがアクティブであることを確認します。ステップ 2 を再実行します。 |
tagIdMismatch: true | タグ URL の ID が --tag-id と異なります。コード内の clientId を修正します。ステップ 2 を再実行します。 |
cspViolations non-empty | ステップ 3 に進みます。 |
ナビゲーション追跡の評価(判断はあなたに委ねられます — これは result には含まれません)
verify はナビゲーションを、採点対象のチェックではなく生の証拠として報告します。時系列順の生データストリームを 2 つ渡すので、アプリ内のナビゲーションが追跡されているかどうかはあなたが判断してください。すべてのアプリに共通する URL 正規化の正解はありません(パスルーティング、/app#about のようなハッシュルーティング、/app?tab=about のようなクエリルーティングがあるため)。そのため、この判断はあなたに委ねられます。
navigations[]— 開発者が行ったすべてのナビゲーションと、完全な URL(ハッシュとクエリを保持)、type(フルページ読み込み/MPA の場合はload、SPA のルート変更の場合はpushState/replaceState/popstate/hashchange)、topフラグ(true= メインフレーム、false= iframe 内)、およびts。pageviewBeacons[]— タグが実際に発火したすべてのページビューと、タグが報告した URL(url)およびts。
判定方法:
-
ナビゲーションが記録されていない場合(
navigationsが空、または初回のloadのみ): 開発者はアプリ内ナビゲーションを試していないため、テストされていません。その旨を伝え、ナビゲーション追跡が機能している、または機能していないと断言しないでください。 -
まずトップフレームのナビゲーションに注目してください(
top: true)。top: falseのエントリーは iframe 内で発生しています。アプリ自体の場合(iframe 内で動作するアプリもあります)もあれば、サードパーティの埋め込みコンテンツ(広告、動画、チャット、決済ウィジェットなど)の場合もあります。pageviewBeacons[]のエントリーで同じ iframe URL が報告されている場合に限り、top: falseのナビゲーションをアプリのナビゲーションとして扱ってください。そうでなければ、ほぼ確実に埋め込みコンテンツなので無視してください。 -
**開発者が訪問したページには、それぞれ対応するページビュービーコンがあるはずです。**文字列の完全一致ではなく、意図をもとに照合してください。
- 報告された
urlがナビゲーション URL と一致するページビュー(完全一致、またはそのアプリのルーティング方式でページを識別する部分が一致するもの)→ そのナビゲーションは追跡されています。 - URL の形式が左右で異なる場合、ナビゲーションの
tsの直後に記録されたページビューのtsは、強い裏付けになります。
- 報告された
-
フルページ(MPA)ナビゲーション(
type: "load"):フルページ読み込みのたびにタグが再読み込みされ、個別のページビューが発生するはずです。読み込みごとにおおむね 1 件のビーコンを想定してください。 -
SPA/ハッシュ/クエリのナビゲーション(
pushState/replaceState/popstate/hashchange、または#…や?…だけが異なる URL):開発者がこのようなページ間を移動したにもかかわらず、タグが新しいページビューを一切発火しなかった場合、タグは URL の変更を追跡していない可能性があります。次の文をそのまま推奨してください。Some in-app navigations did not fire a pageview. If this is a single-page app, enable "Tracking URL Changes" in the Contentsquare app (Project and Users → Tracking URL Changes).
アプリがハッシュまたはクエリ文字列のみでルーティングしている場合は、別のページとして扱うために、Contentsquare プロジェクトで URL 変更の追跡を設定する必要がある可能性も伝えてください。
-
証拠から問題が確認できる場合に限り、推奨してください。ナビゲーションしたすべてのページに一致するページビューがある場合、ナビゲーション追跡は機能しています。その旨を伝えてください。
-
**判断に迷ったら、推測せずコードを確認してください。**照合があいまいな場合(URL が一致しない、タイミングが不明確、ルーティング方式が特殊、またはアプリが iframe 内で動作しているなど)は、結論を出す前にアプリのルーティング設定を調べてください。観測結果を説明できる具体的な情報を得るために、ルーター設定とナビゲーションコード(例:
createRouter/ルート定義、ハッシュモードとヒストリーモードの違い、<a>とクライアントサイドのリンクコンポーネント、リダイレクト/ガード、アプリが iframe 内にマウントされているかどうか)を確認してください。推奨事項は推測ではなく、実際のコードの動作に基づいてください。
ステップ 3 — CSP を修正する(verify で違反が報告された場合のみ)
3.1 既存の CSP を見つける
grep -rn "Content-Security-Policy\|contentSecurityPolicy" next.config.* middleware.* 2>/dev/null
grep -rln "Content-Security-Policy" --include="*.html" --include="*.ejs" --include="*.hbs" --include="*.blade.php" --include="*.erb" . 2>/dev/null | grep -v node_modules
cat package.json | grep -E '"helmet"|"csp-header"|"content-security-policy"' 2>/dev/null
3.2 Contentsquare のドメインを追加する
プロジェクトの既存のディレクティブに追加してください。置き換えず、追記してください。
script-src: 'unsafe-inline' *.contentsquare.net app.contentsquare.com
connect-src: *.contentsquare.net *.contentsquare.com
img-src: *.contentsquare.net
プロジェクトですでに使用している形式(Next.js の headers()、ミドルウェア、<meta> タグ、nginx、helmet)で適用してください。既存の値はすべて保持してください。
例(Next.js の next.config.ts の headers):
"script-src 'self' 'unsafe-inline' *.contentsquare.net app.contentsquare.com",
"connect-src 'self' *.contentsquare.net *.contentsquare.com",
"img-src 'self' *.contentsquare.net",
3.3 再確認する
新しいヘッダーを反映するため、開発者に開発サーバーを再起動するよう依頼してから、ステップ 2に戻り、もう一度 verify を実行してください。cspViolations が空になっていることを確認してください。
成功
verify が result: "pass"(または pass-with-recommendation)を返し、ナビゲーションのトラッキングを評価したら、次のように報告してください。
✅ Contentsquare setup complete!
- Tag installed: <framework> via @contentsquare/tag-sdk
- Tag script loading: ✓
- First pageview sent: ✓
- Navigation tracking: <your assessment — see below>
- CSP: <no issues / fixed>
CSP 違反が報告された場合は、recommendation をそのまま追加してください。ナビゲーションの評価でトラッキングされていない SPA/ハッシュ/クエリのナビゲーションが見つかった場合は、トラッキング URL の変更に関する推奨事項をそのまま追加してください。
ナビゲーションのトラッキングについての記述方法(開発者に誤解を与えないようにする)
verify が返すのは生の証拠であり、スコアではありません。navigations[](開発者がアクセスしたページ)と pageviewBeacons[](タグが報告した内容)を自分で照合し、記述内容を導き出してください。pageviews sent の数を決して作り上げないでください。
- ページについて、たとえば「アクセスしたすべてのページでページビューが記録された」のように記述するか、記録されなかった特定のページを挙げてください。「N 件のページビューが送信された」とは言わないでください。ページとネットワークビーコンを混同し、開発者に誤解を与えます。
navigations[].urlのページをpageviewBeacons[].urlと照合して列挙してください。- 開発者が同じページに複数回アクセスしても、そのページは 1 回だけ数えてください。生のストリームには重複や
replaceState/loadの連続イベントが含まれることがあるため、要約時にまとめてください。 navigationsが空(または最初のloadしか含まれていない)の場合は、アプリ内ナビゲーションが試されておらず、ナビゲーショントラッキングもテストされていないと伝えてください。合格または失敗として報告しないでください。
トラブルシューティング
| 問題 | 解決方法 |
|---|---|
| タグが読み込まれない | injectContentsquareScript がクライアントサイドでのみ実行されることを確認してください(useEffect、onMount、.client.ts)。 |
injectContentsquareScript is not a function | @contentsquare/tag-sdk がインストールされ、正しくインポートされていることを確認してください。 |
verify にナビゲーションが記録されない | Done をクリックする前に、開発者が実際にアプリ内のルートをクリックして移動する必要があります。 |
| ブラウザーが起動しない | --install-browser を付けて再実行するか、Google Chrome をインストールしてください。 |
| 修正後も CSP エラーが続く | 新しいヘッダーが配信されるよう、開発サーバーを再起動する必要があります。 |
.contentsquare.com による違反 | connect-src に *.contentsquare.net と *.contentsquare.com の両方を追加してください。 |