トランクベース開発を加速するVercel Feature Flags入門 - Flags SDK・Toolbar・Edge Configの使い方

トランクベース開発を加速するVercel Feature Flags入門 - Flags SDK・Toolbar・Edge Configの使い方

2026.01.17

こんにちは、豊島です。

今回は、トランクベース開発を実践する上で役立つVercelのFeature Flagsについて、その魅力と具体的な活用方法を解説します。

はじめに

トランクベース開発は、すべての開発者が単一のブランチに頻繁にコミットし、短期間のフィーチャーブランチを使用する開発戦略です。
この手法により、マージコンフリクトを最小化し、継続的インテグレーション(CI)を実現できます。しかし、トランクベース開発を成功させるには、本番環境へのデプロイと機能の有効化を分離する仕組みが不可欠です。

そこで活躍するのが、Vercelが提供するFeature Flagsです。VercelのFeature Flagsはトランクベース開発のワークフローに深く統合された、フロントエンド開発のライフサイクル全体を加速させる機能です。

この記事では、Vercelが提供するFeature Flags関連の機能を紹介し、トランクベース開発での活用方法を解説します。
具体的には、以下の3つの機能を紹介します。

コンポーネント 主な役割 特徴
Flags SDK アプリケーション内でのフラグ評価 Next.js/SvelteKitに最適化されたオープンソース
Vercel Toolbar 開発・QA時のフラグ操作 ブラウザから直接フラグ値をオーバーライドして、リアルタイムで挙動を確認できる
Edge Config グローバルな設定データストア 超低遅延でのデータ読み取り、A/Bテストやリダイレクトに適しています

これらのツールを組み合わせることで、単純な機能のON/OFFだけでなく、ユーザー属性に基づいたパーソナライゼーション、段階的な機能のロールアウトといったリリース戦略を実現することができます。

Flags SDKについて

@vercel/flagsは、Next.jsやSvelteKitアプリケーションにフィーチャーフラグを統合するためのライブラリです。サーバーサイドでの評価を基本としており、パフォーマンスへの影響を最小限に抑える設計思想が貫かれています。

https://flags-sdk.dev/

flagsの定義と使い方の例

フラグの定義はlib/flags.tsのような共通ファイルにまとめると管理しやすくなります。
decide内でリクエスト情報(headers, cookies)を活用することも可能です。

lib/flags.ts

import { flag } from 'flags/next'

// シンプルなbooleanの例
export const showNewFeature = flag<boolean>({
  key: 'new-feature',
  decide: () => process.env.ENABLE_NEW_FEATURE === 'true',
})

// リクエストヘッダー(地域情報)を使う例
type GDPRBannerEntities = {
  country: string
}

export const enableGDPRBanner = flag<boolean, GDPRBannerEntities>({
  key: 'gdpr-banner',
  identify({ headers }): GDPRBannerEntities {
    return {
      country: headers.get('x-vercel-ip-country') || 'US',
    }
  },
  decide({ entities }) {
    const euCountries = ['DE', 'FR', 'ES', 'IT'] // 他のEU加盟国も追加
    return euCountries.includes(entities.country)
  },
})

// クッキー(ユーザーティア)に応じて変える例
export type BannerTheme = 'default' | 'premium' | 'sale'

type HeroBannerEntities = {
  userTier: string | undefined
}

export const heroBannerTheme = flag<BannerTheme, HeroBannerEntities>({
  key: 'hero-banner-theme',
  identify({ cookies }): HeroBannerEntities {
    return {
      userTier: cookies.get('user_tier')?.value,
    }
  },
  decide({ entities }) {
    if (entities.userTier === 'premium') {
      return 'premium'
    }
    if (process.env.IS_SALE_PERIOD === 'true') {
      return 'sale'
    }
    return 'default'
  },
})

これに加えDedupePrecomputeなど、より実践的な内容については各ドキュメントを確認してください。

コンポーネントでのフラグ評価

定義したフラグは、サーバーコンポーネントやAPIルートで評価します。

import { showNewFeature, enableGDPRBanner, heroBannerTheme } from '@/lib/flags'
import { GDPRBanner, NewFeatureComponent, HeroBanner } from '@/components'

export default async function HomePage() {
  // 複数のフラグをパラレルで評価
  const [isNewFeatureEnabled, isGDPRBannerEnabled, bannerTheme] = await Promise.all([
    showNewFeature(),
    enableGDPRBanner(),
    heroBannerTheme(),
  ])

  return (
    <main>
      <HeroBanner theme={bannerTheme} />
      {isNewFeatureEnabled && <NewFeatureComponent />}
      {isGDPRBannerEnabled && <GDPRBanner />}
    </main>
  )
}

次は定義したフラグを開発中に手軽に切り替えられるVercel Toolbarを紹介します。

Vercel Toolbarについて

Vercel Toolbarを導入すると、開発中やプレビュー環境で、ブラウザから直接フィーチャーフラグの値を上書きして挙動を確認できます。
これにより、デプロイなしで様々なシナリオをテストすることができます。

Toolbarの有効化について

設定周りはドキュメントに記載のある通りで、
https://vercel.com/docs/vercel-toolbar/in-production-and-localhost

プレビュー環境(Vercelに接続しているブランチやPRから作成される確認用の環境)にToolbarが表示されます。
Arc-2025-12-18 002309

ここからFlags Explorerを押すといくつか変更を加えることができます。
試しにsummer-saleをOnにしApplyすると、
Arc-2025-12-18 002311

Summer Saleのバナーが表示されました。
Arc-2025-12-18 002313

カートのページではSummer discountも入っています。
Arc-2025-12-18 002315

このように、デプロイ不要でUIの変更及び挙動を確認することができます。

flagsを使ったサンプルコードは公開されているため、詳細はリポジトリをご確認ください。

ここまでは環境変数でフラグを管理していましたが、フラグの値を変更するたびにデプロイが必要になります。次のセクションではデプロイなしでフラグの値を動的に変更できるEdge Configを紹介します。

Edge Configについて

これまでの例では環境変数でフラグを管理していました。しかし、フラグの値を変更するたびにデプロイが必要になります。
Edge Configを使えば、Vercelダッシュボードからデプロイなしでフラグの値を変更でき、かつVercelのグローバルエッジネットワーク上にデータを配置することで超低遅延で読み取ることができます。頻繁に読み取られ、更新頻度が低いデータの保存に適しています。

Edge Configのセットアップ

VercelダッシュボードでEdge Configを作成し、設定を進めます。

https://vercel.com/docs/edge-config/get-started

Edge Configを使ったフラグの定義

以下は、Edge Configを使ったシンプルなフラグ定義の例です。Edge Configに格納した値をadapter経由で取得し、decide関数で評価します。

lib/flags.ts

import { flag } from 'flags/next'
import { edgeConfigAdapter } from '@flags-sdk/edge-config'

// Edge Configからブーリアン値を取得
export const showBetaDashboard = flag<boolean>({
  key: 'beta-dashboard',
  adapter: edgeConfigAdapter(),
  decide({ value }) {
    return value ?? false
  },
})

// Edge Configに 'A' または 'B' を直接格納するパターン
// 全ユーザーに同じバリアントを表示(段階的ロールアウト向け)
export const checkoutVariant = flag<'A' | 'B'>({
  key: 'checkout-variant',
  adapter: edgeConfigAdapter(),
  decide({ value }) {
    return value === 'A' || value === 'B' ? value : 'A'
  },
})

Edge Middlewareでの活用

Edge Configの真価は、Middlewareと組み合わせることで発揮されます。
オリジンサーバーに到達する前に、エッジでリクエストを書き換えたり、リダイレクトしたりできます。

Feature Flagsの文脈では、Edge ConfigとMiddlewareを組み合わせることで、メンテナンスモードの切り替えや、特定のIPアドレスからのアクセス制御などを動的に行うことができます。
以下はその簡易的な例です。本番運用では、503ステータスコードの返却やログの詳細化など、追加の考慮が必要になります。

middleware.ts

import { NextResponse, type NextRequest } from 'next/server'
import { get } from '@vercel/edge-config'

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
}

export async function middleware(request: NextRequest) {
  const { nextUrl, ip } = request

  try {
    const [isMaintenance, blockedIps] = await Promise.all([
      get<boolean>('isMaintenance').then(v => v ?? false),
      get<string[]>('blockedIps').then(v => v ?? []),
    ])

    // IPブロック
    if (ip && blockedIps.includes(ip)) {
      return new NextResponse('Forbidden', { status: 403 })
    }

    // メンテナンスモード
    const isMaintenancePath =
      nextUrl.pathname === '/maintenance' ||
      nextUrl.pathname.startsWith('/maintenance/')

    if (isMaintenance && !isMaintenancePath) {
      return NextResponse.rewrite(new URL('/maintenance', request.url))
    }

    return NextResponse.next()
  } catch (error) {
    console.error('Edge Config error:', error)
    return NextResponse.next()
  }
}

実践Tips

Feature Flagsを本番運用する際に役立つTipsを紹介します。

フラグの命名規則

チームで一貫した命名規則を決めておくと管理しやすくなります。

パターン 用途
enable-* enable-dark-mode 機能のON/OFF
show-* show-beta-banner UI要素の表示制御
use-* use-new-checkout 実装の切り替え

不要になったフラグの削除

フラグは技術的負債になりやすいため、定期的に棚卸しを行うことが重要です。

  • 全ユーザーに展開完了したフラグは、コードからフラグ判定を削除
  • Edge ConfigやVercelダッシュボードから設定を削除
  • 削除漏れを防ぐため、フラグ作成時に「削除予定日」を記載しておくと効果的

本番運用での注意点

  • デフォルト値を必ず設定: Edge Configの接続障害に備えて、フラグには必ずデフォルト値を設定
  • 段階的ロールアウト: 新機能は一部ユーザーから段階的に展開し、問題がないことを確認してから全体展開
  • 監視の設定: フラグの切り替え前後でエラー率やパフォーマンスに変化がないか監視。今回は簡易的なコード例のため最小限のログ出力にしていますが、本番運用ではパス、IP、タイムスタンプなどを含めた詳細なログ設計を検討してください

まとめ

本記事では、Vercelが提供するFeature Flags関連の3つの機能を紹介しました。

  • Flags SDK: アプリケーション内でフラグを定義・評価するためのライブラリ
  • Vercel Toolbar : 開発・QA時にブラウザからフラグを操作できるツール
  • Edge Config: 超低遅延でフラグの値を読み取れるデータストア

これらを組み合わせることで、コードのデプロイと機能のリリースを分離し、安全かつ柔軟なリリース戦略を実現できます。
トランクベース開発を実践している方、これから導入を検討している方は、ぜひVercelのFeature Flagsを試してみてください。

この記事をシェアする

FacebookHatena blogX

関連記事