@feelflow/ffid-sdk
v1.13.0
Published
FeelFlow ID Platform SDK for React/Next.js applications
Maintainers
Readme
@feelflow/ffid-sdk
FeelFlow ID Platform SDK — React/Next.js 向け + サーバーサイドモジュールはフレームワーク非依存。
5行のコードでFFID認証を導入!
インストール
npm install @feelflow/ffid-sdk
# or
yarn add @feelflow/ffid-sdk
# or
pnpm add @feelflow/ffid-sdk統合ガイド
サービスを FFID Platform に統合する詳細なガイドは Integration Guide を参照してください。OAuth フロー、フロントエンド/バックエンド実装パターン、セキュリティチェックリスト、アンチパターン集を網羅しています。
クイックスタート
1. プロバイダーを設定(5行で完了!)
// app/layout.tsx
import { FFIDProvider } from '@feelflow/ffid-sdk'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="ja">
<body>
<FFIDProvider serviceCode="chatbot">{children}</FFIDProvider>
</body>
</html>
)
}2. 認証情報を使用
import { useFFID, useSubscription } from '@feelflow/ffid-sdk'
function Dashboard() {
const { user, isAuthenticated, login, logout } = useFFID()
const { isActive, planCode } = useSubscription()
if (!isAuthenticated) {
return <button onClick={login}>ログイン</button>
}
return (
<div>
<p>Welcome, {user.displayName ?? user.email}!</p>
<p>プラン: {planCode}</p>
<button onClick={logout}>ログアウト</button>
</div>
)
}UIコンポーネント
import {
FFIDLoginButton,
FFIDUserMenu,
FFIDOrganizationSwitcher,
FFIDSubscriptionBadge,
} from '@feelflow/ffid-sdk/components'
function Header() {
return (
<header>
<FFIDLoginButton>ログイン</FFIDLoginButton>
<FFIDOrganizationSwitcher />
<FFIDSubscriptionBadge />
<FFIDUserMenu />
</header>
)
}コンポーネントのスタイリング(classNames パターン)
各UIコンポーネントは Radix UI スタイルパターン に従った classNames プロップをサポートしています。これにより、コンポーネントの各パーツに個別のクラスを適用できます。
FFIDUserMenu
<FFIDUserMenu
classNames={{
container: 'relative', // ラッパー要素
button: 'focus:ring-2', // アバターボタン(トリガー)
avatar: 'rounded-full', // アバター画像/フォールバック
menu: 'shadow-lg', // ドロップダウンメニュー
userInfo: 'border-b', // ユーザー情報セクション
menuItem: 'hover:bg-gray-100', // カスタムメニュー項目
logout: 'text-red-600', // ログアウトボタン
}}
/>FFIDOrganizationSwitcher
<FFIDOrganizationSwitcher
classNames={{
container: 'relative', // ラッパー要素
button: 'border rounded', // トリガーボタン
dropdown: 'shadow-md', // ドロップダウンメニュー
option: 'px-4 py-2', // 各組織オプション
optionSelected: 'bg-blue-50', // 選択中の組織(optionに加えて適用)
}}
/>FFIDSubscriptionBadge
<FFIDSubscriptionBadge
classNames={{
badge: 'font-semibold', // バッジspan要素
}}
/>Note:
FFIDLoginButtonはシンプルな単一要素コンポーネントのため、標準のclassNameプロップのみをサポートしています。
API リファレンス
FFIDProvider
アプリケーション全体をラップするプロバイダーコンポーネント。
<FFIDProvider
serviceCode="chatbot" // 必須: サービスコード
apiBaseUrl="..." // オプション: カスタムAPIエンドポイント
debug={true} // オプション: デバッグログ有効化(非推奨、loggerを使用)
logger={customLogger} // オプション: カスタムロガー(下記参照)
refreshInterval={300000} // オプション: セッション更新間隔(ms)
onAuthStateChange={(user) => {}} // オプション: 認証状態変更時コールバック
onError={(error) => {}} // オプション: エラー時コールバック
>
{children}
</FFIDProvider>カスタムロガー
SDKのデバッグ出力をカスタマイズできます。デフォルトではログは出力されません(サイレント)。
import type { FFIDLogger } from '@feelflow/ffid-sdk'
import pino from 'pino' // または winston, bunyan 等
// アプリケーションのロガーインスタンス
const appLogger = pino({ level: 'debug' })
// FFID SDK用にラップ
const ffidLogger: FFIDLogger = {
debug: (...args) => appLogger.debug({ sdk: 'ffid' }, ...args),
info: (...args) => appLogger.info({ sdk: 'ffid' }, ...args),
warn: (...args) => appLogger.warn({ sdk: 'ffid' }, ...args),
error: (...args) => appLogger.error({ sdk: 'ffid' }, ...args),
}
// 使用例
<FFIDProvider serviceCode="chatbot" logger={ffidLogger}>
{children}
</FFIDProvider>ロガー優先順位:
loggerが指定されている場合 → カスタムロガーを使用debug: trueでloggerなし →consoleを使用(後方互換性)- 両方なし → サイレント(no-op)
useFFID()
ユーザー・組織情報を取得するフック。
const {
user, // FFIDUser | null - 現在のユーザー
organizations, // FFIDOrganization[] - 所属組織一覧
currentOrganization, // FFIDOrganization | null - 現在の組織
isLoading, // boolean - ロード中
isAuthenticated, // boolean - 認証済み
login, // () => void - ログインページへリダイレクト
logout, // () => Promise<void> - ログアウト
switchOrganization, // (id: string) => void - 組織切り替え
refresh, // () => Promise<void> - セッション更新
} = useFFID()useSubscription()
契約情報を取得するフック。
const {
subscription, // FFIDSubscription | null - 現在のサブスクリプション
planCode, // string | null - プランコード
isActive, // boolean - アクティブ契約
isTrialing, // boolean - トライアル中
isCanceled, // boolean - 解約済み
hasPlan, // (plans: string | string[]) => boolean - プラン確認
hasAccess, // () => boolean - アクセス権確認
} = useSubscription()withSubscription()
サブスクリプション確認HOC。
const PremiumFeature = withSubscription(MyComponent, {
plans: ['pro', 'enterprise'],
fallback: <UpgradePrompt />,
loading: <Spinner />,
})型定義
interface FFIDUser {
id: string
email: string
displayName: string | null
avatarUrl: string | null
locale: string | null
timezone: string | null
createdAt: string
}
interface FFIDOrganization {
id: string
name: string
slug: string
role: 'owner' | 'admin' | 'member'
status: 'active' | 'invited' | 'suspended'
}
interface FFIDSubscription {
id: string
serviceCode: string
serviceName: string
planCode: string
planName: string
status: 'trialing' | 'active' | 'past_due' | 'canceled' | 'paused'
currentPeriodEnd: string | null
}OAuth userinfo の契約要約
token mode では SDK は /api/v1/oauth/userinfo を呼び出し、基本プロフィールに加えてサービス契約の要約を受け取ります。
この要約により、追加 API を呼ばずにプラン判定や UI 分岐を行えます。
interface FFIDOAuthUserInfoSubscription {
subscriptionId: string | null
status: 'trialing' | 'active' | 'past_due' | 'canceled' | 'paused' | null
planCode: string | null
seatModel: 'organization' | null
memberRole: 'owner' | 'admin' | 'member' | 'viewer' | null
organizationId: string | null
}seatModel はシートモデル識別用であり、organization と role は userinfo の解決済み組織文脈として扱います。
React 以外の環境で使う
本 SDK は React/Next.js 向けに設計されていますが、一部のモジュールはフレームワーク非依存で利用できます。
サーバーサイドモジュール(React 依存なし)
以下の subpath exports は React に一切依存しません。Node.js、Deno、Bun 等で即座に利用できます。
// 利用規約・法的文書
import { createFFIDLegalClient } from '@feelflow/ffid-sdk/legal'
// Agency(代理店)管理
import { createFFIDAgencyClient } from '@feelflow/ffid-sdk/agency'
// お知らせ取得
import { createFFIDAnnouncementsClient } from '@feelflow/ffid-sdk/announcements'
// Webhook 署名検証・ハンドラー(※ Node.js crypto が必要)
import { createFFIDWebhookHandler, verifyWebhookSignature } from '@feelflow/ffid-sdk/webhooks'Note:
webhooksモジュールは Node.js のcryptoモジュールとBufferを使用します。Cloudflare Workers で利用する場合はnodejs_compat互換フラグを有効にしてください。
これらのモジュールは独立した subpath export として公開されているため、メインエントリ (@feelflow/ffid-sdk) を経由せず、React の依存が伝播しません。
createFFIDClient を非 React 環境で使う
非 React 環境では、可能な限り上記の subpath exports(/legal、/webhooks 等)の個別クライアントを使用してください。メインエントリの createFFIDClient を使う必要がある場合、createFFIDClient 自体は React を使用しませんが、メインエントリに含まれるため bundler 環境では React を external に指定する必要があります。
Cloudflare Workers
ビルドコマンドで --external を指定するか、カスタム esbuild 設定で external を設定してください。
# wrangler のビルドコマンド例
esbuild src/index.ts --bundle --format=esm --external:react --external:react-domVue / Nuxt(Vite)
// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
external: ['react', 'react-dom'],
},
},
})esbuild
esbuild src/index.ts --bundle --external:react --external:react-domwebpack
// webpack.config.js
module.exports = {
externals: {
react: 'react',
'react-dom': 'react-dom',
},
}Note: サーバーサイドで bundler を使わずに実行する場合、subpath exports(
@feelflow/ffid-sdk/legal等)を使用すれば external 設定なしで React がインストールされていなくても動作します。メインエントリ(@feelflow/ffid-sdk)を ESM で import する場合は、モジュールグラフが静的に解決されるため React が必要です。
peerDependencies は optional です
SDK の package.json で react / react-dom は optional: true に設定済みです(利用者側での設定は不要)。React をインストールしなくても npm install 時に warning は発生しません。
// SDK の package.json に設定済み(参考)
{
"peerDependenciesMeta": {
"react": { "optional": true },
"react-dom": { "optional": true }
}
}環境変数
オプションで環境変数を使用してデフォルト設定を上書きできます:
NEXT_PUBLIC_FFID_API_URL=https://id.feelflow.net
NEXT_PUBLIC_FFID_SERVICE_CODE=chatbotライセンス
MIT
