btst-integration について
btst-integration は、アプリケーションへの BTST stack の導入を案内するスキルです。バックエンドとクライアントのプラグイン設定から、ルート、プロバイダー、スキーマ、マイグレーションまで扱い、フレームワーク別のエントリーポイントとアダプター選択も説明します。
主な機能
- 01バックエンドとクライアントのプラグイン設定
- 02API とページルートの接続
- 03プロバイダーと CSS インポートの設定
- 04データベーススキーマの生成
- 05Kysely マイグレーションの実行
活用シーン
- 01アプリケーションに BTST プラグインを追加
- 02プラグインルートをフレームワークに接続
- 03データベースアダプター用スキーマの生成
- 04Kysely データベース移行の準備
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ better-stack-ai/ better-stack --skill btst-integrationインストール後、Claude Code で/btst-integrationを入力して読み込まれたか確認します。
同梱ファイルREFERENCE.md
詳細
BTST ライブラリの統合
クイックスタート
@btst/stack、@tanstack/react-query、およびいずれか1つの@btst/adapter-*をインストールします。- 各プラグインのバックエンド側とクライアント側をインストールして登録します。
lib/stack.tsを作成し、{ handler, dbSchema }をエクスポートします。- フレームワークの API エントリーファクトリーを使って、
/api/data/*にhandlerをマウントします。 - グローバル CSS で、プラグインごとに
@import "@btst/stack/plugins/{plugin}/css"を追加します。 lib/stack-client.tsx、lib/query-client.ts、およびフレームワークのページエントリーファクトリーを使った/pages/*のキャッチオールルートを作成します。QueryClientProviderとStackProviderを含むページの レイアウト ファイルを作成します。@btst/cli generateを実行します(Kysely の場合はmigrateも実行します)。
各ファイルのコード構成については、REFERENCE.md をご覧ください。
ワークフロー
1) 前提条件とパッケージのインストール
- 前提条件:shadcn/ui(CSS 変数を有効化)、Sonner の
<Toaster />、Tailwind v4。 - インストールするもの:
@btst/stack、@tanstack/react-query、およびいずれか1つのアダプター:@btst/adapter-prisma/@btst/adapter-drizzle/@btst/adapter-kysely/@btst/adapter-mongodb@btst/adapter-memory— 開発・テスト専用で、本番環境では使用しないでください
- 各プラグインパッケージは
@btst/stackと一緒にインストールします(これらはモノレポパッケージ内に含まれています)。
2) プラグインの登録(バックエンド + クライアント)
- バックエンド(
lib/stack.ts):@btst/stack/plugins/{plugin}/apiから{plugin}BackendPluginをインポートします。- バックエンドプラグインのオプションオブジェクトにフックと設定を渡します(例:
blogBackendPlugin({ hooks }))。 - 複合名のプラグインでは、camelCase のキーを使用します:
aiChat、formBuilder、uiBuilder。
- バックエンドプラグインのオプションオブジェクトにフックと設定を渡します(例:
- クライアント(
lib/stack-client.tsx):@btst/stack/plugins/{plugin}/clientから{plugin}ClientPluginをインポートします。- クライアント定義に渡すのは、
seo、フック、ページコンポーネントなど、プラグイン固有のオプションのみです。api、site、queryClientはcreateClientStack()で一度だけ設定します。リゾルバーが、そのランタイムを各定義にバインドします。 - 受信した SSR リクエストヘッダーは、トップレベルの
createClientStack({ api: { headers } })設定を通じて渡します。 - サーバー上で信頼できる API/サイトオリジンのスナップショットを1つ解決し、プロバイダーにハイドレートします。管理されたバックエンドでは、異なる
BTST_API_URLを使用する場合があります。ハイドレーション後にwindow.locationから再構築しないでください。
- クライアント定義に渡すのは、
3) バックエンドスタックの設定
- アプリケーションの認可が有効な場合は、
createBackendStack({ basePath: "/api/data", plugins: { ... }, adapter: (db) => createXxxAdapter(..., db, {}), auth: serverAuth })を呼び出します。 createServerAuth({ authorization, getIdentity })でserverAuthを作成します。authを省略すると、意図的に認可なしの許容的な互換動作が維持されます。AI Chat のaccess: "authorized"などのプラグインラベルだけでは、認可の強制境界にはなりません。handlerとdbSchemaをエクスポートします。- Memory アダプター + Next.js:同一プロセス内で2つのインスタンスが作成されるのを防ぐため、
globalThisに固定します:function createAppStack() { return createBackendStack({ ... }) } type AppStack = ReturnType<typeof createAppStack> const g = globalThis as typeof globalThis & { __btst__?: AppStack } export const myStack = g.__btst__ ??= createAppStack() export const { handler, dbSchema } = myStack
4) CSS — グローバルスタイルシートを編集
Tailwind レイヤーの前に、プラグインごとに1行追加します:
@import "@btst/stack/plugins/blog/css";
@import "@btst/stack/plugins/cms/css";
@import "@btst/stack/plugins/ai-chat/css";
/* …one per selected plugin */
重複させないでください。パッチ適用と手動編集のどちらも冪等である必要があります。
5) フレームワークのルートとクライアントランタイムを接続する
- API ルート:フレームワークのエントリーポイントから
toNextRouteHandlers、toReactRouterHandlers、またはtoTanStackHandlersを使用します。 - ページルート:
createNextPage、createReactRouterPage、またはcreateTanStackPageOptionsを使用します。このファクトリーが、ルートのマッチング、ローダーの実行順序、ハイドレーション、メタデータ、404 の処理を担います。 - ページレイアウト(Next.js の
"use client"):QueryClientProvider、続けてStackProviderでラップします。- 解決済みのクライアントスタックを
stack={clientStack}で渡します。そのトップレベルのsite.basePathは、ページのキャッチオールプレフィックスと一致する必要があります。 - フレームワーク全体でリンク、画像、ナビゲーション、更新を行うには、
router={nextRouter()}/reactRouter()/tanstackRouter()を指定します。 - プラグインで ID または権限の表示制御が必要な場合は、
auth={createClientAuth({ authorization, getIdentity, loginPath })}を指定します。 overrides={{ pluginKey: { uploadImage?, ...pluginSpecificValues } }}は、プラグイン固有のカスタマイズにのみ使用します。- 解決済みのプラグインマップにオーバーライドのキーと値を推論させ、手動のプロバイダーマップを重複して作成しないでください。
- プロバイダーの接続方法と、プラグインごとのオーバーライドの形式については、REFERENCE.md を参照してください。
- 解決済みのクライアントスタックを
- ai-chat プラグインのみ:
PageAIContextProviderで ルートレイアウト(StackProviderの上位)をラップします。
ページではimport { PageAIContextProvider } from "@btst/stack/plugins/ai-chat/client/context" // root layout.tsx (not the pages layout) export default function RootLayout({ children }) { return <PageAIContextProvider>{children}</PageAIContextProvider> }useRegisterPageAIContext(...)を呼び出して AI コンテキストを登録します。btst-ai-contextスキルを参照してください。
6) スキーマを生成してマイグレーションを実行する
@btst/cliを開発依存関係としてインストールします。- Prisma:
npx @btst/cli generate --config=lib/stack.ts --orm=prisma --output=schema.prisma - Drizzle:
npx @btst/cli generate --config=lib/stack.ts --orm=drizzle --output=src/db/schema.ts - Kysely:
npx @btst/cli generate --config=lib/stack.ts --orm=kysely --output=migrations/schema.sql --database-url=... - Kysely のマイグレーション:
npx @btst/cli migrate --config=lib/stack.ts --database-url=... - Prisma/Drizzle:generate の実行後、ネイティブのマイグレーションツールを使用します。
検証チェックリスト
stack.tsがhandlerとdbSchemaの両方をエクスポートしている。- 保護されたアプリケーションでは、
createBackendStack({ auth })にcreateServerAuth(...)を渡している。auth を省略すると、意図的に制限のない状態になります。 - すべてのプラグインが、バックエンド側とクライアント側の両方に登録されている。
- API の
basePathとcreateBackendStack({ basePath })が完全に一致している。 - API とページのキャッチオールルートで、フレームワークのエントリーファクトリーを使用している。
- ページレイアウトが
"use client"であり、QueryClientProvider、続けてStackProviderでラップされている。 - 解決済みのクライアントスタックの
site.basePathが、/pagesのキャッチオールルートプレフィックスと一致している。 - グローバル CSS に、選択したプラグインごとに 1 行の
@importがある。 /pages/*ルートで、想定どおりのプラグインページがレンダリングされる。- CLI コマンドの実行時に、必要な環境変数が有効になっている。
注意点
- ページレイアウトに
"use client"がない —StackProviderはフックを使用するため、クライアント側で動作させる必要があります。 - キーの大文字・小文字が誤っている — バックエンドとクライアントのプラグインマップのキーは一致させる必要があります。複合名はキャメルケースを使用します(
ai-chatではなくaiChat)。 - CSS インポートがない — データが正しく読み込まれていても、プラグインの UI が何も表示されないまま動作しなくなります。
- プラグインの登録が片側だけ — バックエンド側のみの場合はルートが存在せず、クライアント側のみの場合はデータ呼び出しが 404 になります。
- Next.js でのメモリーアダプター — API とページのバンドル間で 1 つのインメモリストアを共有できるよう、必ず
globalThisに固定します。 - CLI でのパスエイリアス —
@btst/cliは設定ファイルを直接実行します。lib/stack.tsとその依存ファイルでは相対インポートを使用してください。 - Kysely の generate には DB が必要 —
DATABASE_URLまたは--database-urlを渡します。.env.localにはdotenv-cliを使用します。 - プロバイダーサービスをプラグインのオーバーライドにコピーしている — 組み込みプラグインのオーバーライドには、
Link、Image、ナビゲーション、更新、API パス、ID、ログインの値を追加しないでください。トップレベルのrouter、api、authを使用します。
コメント
Markdown 対応