Next.js App Router への組み込み(cside-sdk)
導入はフェーズ 1:AI 設定(CSide コンソールと資格情報)と、フェーズ 2:サイトへの組み込み(Next.js App Router への cside-sdk の追加)に分けます。サーバー側は cside-sdk/next、UI は cside-sdk/react を利用します。
フェーズ 1:AI 設定
CSide の管理画面で、埋め込むチャットがどのように応答するかを固めます。ここまで終えると、フェーズ 2 でアプリ側から参照する値が揃います。
- アカウント作成とワークスペース/プロジェクトの準備
- エージェントの作成と案内内容の設定(テンプレートやウィザードでたたき台を作り、文言や許可範囲を調整)
- ナレッジやルール、公開スコープを確認して公開・反映する
- API キーとエージェント IDをコンソールから取得する(フェーズ 2 の環境変数に転記)
アプリ側の環境変数(フェーズ 1 の値を転記)
Next.js プロジェクトルートの .env.local に、コンソールで発行した値を設定する(キー名は固定)。API キーなど秘密情報はリポジトリにコミットしない。
CSIDE_API_KEY=
CSIDE_AGENT_ID=ルートレイアウトはサーバーで評価できるため、 CSIDE_AGENT_ID に NEXT_PUBLIC_ は通常不要。
フェーズ 2:サイトへの組み込み
フェーズ 1 が済んだうえで、対象の Next.js アプリに SDK とエンドポイントを追加します。CLI が .env.local を自動編集することはありません。
対象のアプリケーション(Next.js、App Router)
以降の手順は App Router 向けです。作業前に次を満たすこと。
package.jsonにnext依存があることapp/またはsrc/app/にルートレイアウト(例:layout.tsx)やルートがあり、App Router として成立していること
次の場合は cside-sdk の導入・変更は行わない
- Pages Router のみ(
appがなくpagesのみ)と判断できる場合
構成が不明瞭で判定できない場合は推測で進めず、ルートレイアウトのパスや不足情報を確認する。
npm install と npx cside コマンド
プロジェクトルートで実行する。
npm install cside-sdk && npx cside initサーバー再起動
開発サーバーを再起動して反映を確認する。組み込みが成功していればチャットウィジェットが画面右下に表示される想定。
npm run devnpx cside init を使わない場合
npx cside init の代わりに、依存関係とファイルを手作業で追加する。
1. 依存関係
npm install cside-sdk2. API ルート
app/api/cside/[[...slug]]/route.ts を追加する。ルートが src/app の場合は src/app/api/cside/[[...slug]]/route.ts。
import {
handleCsideChatPost,
handleCsideEmbedContextGet,
handleCsideHostApiPreparePost,
} from "cside-sdk/next";
export const runtime = "nodejs";
export const maxDuration = 60;
type CsideSlug = string[] | undefined;
function routeKey(slug: CsideSlug): "chat" | "embed-context" | "prepare" | null {
if (!slug?.length) return null;
if (slug.length === 1 && slug[0] === "chat") return "chat";
if (slug.length === 1 && slug[0] === "embed-context") return "embed-context";
if (slug.length === 2 && slug[0] === "host-api" && slug[1] === "prepare") return "prepare";
return null;
}
export async function GET(
req: Request,
ctx: { params: Promise<{ slug?: string[] }> },
): Promise<Response> {
const { slug } = await ctx.params;
if (routeKey(slug) === "embed-context") return handleCsideEmbedContextGet(req);
return Response.json({ error: "Not found" }, { status: 404 });
}
export async function POST(
req: Request,
ctx: { params: Promise<{ slug?: string[] }> },
): Promise<Response> {
const { slug } = await ctx.params;
const key = routeKey(slug);
if (key === "chat") return handleCsideChatPost(req);
if (key === "prepare") return handleCsideHostApiPreparePost(req);
return Response.json({ error: "Not found" }, { status: 404 });
}
3. Tailwind v4
app/globals.css の末尾に追記する例。
/* cside-sdk */
@source "../node_modules/cside-sdk/dist/**/*.mjs";
src/app/globals.css なら、ファイル位置から node_modules/cside-sdk/dist への相対パスに読み替える(例: @source "../../node_modules/cside-sdk/dist/**/*.mjs";)。
4. ルートレイアウト
既存の html / body / children を壊さず CsideProvider で包む。 agentId には process.env.CSIDE_AGENT_ID ?? "" を渡す。
import type { ReactNode } from "react";
import { CsideProvider } from "cside-sdk/react";
export default function Layout({ children }: { children: ReactNode }) {
const agentId = process.env.CSIDE_AGENT_ID ?? "";
return (
<html lang="ja">
<body>
<CsideProvider agentId={agentId}>
{children}
</CsideProvider>
</body>
</html>
);
}
注意
- API キーなど秘密情報をリポジトリにコミットしない
- Tailwind の
@sourceはプロジェクト構成に合わせて調整する
