Next.js と Vercel Edge Functions で実現する、パーソナライズ体験 〜LaunchDarkly で動的コンテンツをエッジで出し分ける技術〜

現代のWebフロントエンド開発は、大きなジレンマを抱えています。ユーザーは自分に最適化されたリッチなパーソナライズ体験を期待する一方で、Google の Core Web Vitals に代表されるように、ウェブサイトのパフォーマンス、特に表示速度に対する要求はかつてなく高まっています。

従来、パーソナライゼーションはクライアント サイドで実装されることが多く、ページの読み込み後に JavaScript が実行され、コンテンツが動的に書き換わっていました。しかし、この手法は表示のちらつきやレイアウトのズレ(CLS – Cumulative Layout Shift)を引き起こしやすく、ユーザー体験とパフォーマンスの両面で課題がありました。

では、最高のパフォーマンスを維持しながら、ユーザー一人ひとりに最適化されたコンテンツを提供することは可能なのでしょうか?

答えは「YES」です。本記事では、このトレードオフの関係を解消する最先端のアーキテクチャとして、Next.jsVercel Edge Functions、そして LaunchDarkly を組み合わせた「エッジ・パーソナライゼーション」の具体的な実装方法を解説します。

LaunchDarkly に関する情報、お問い合わせはこちらから

アドバンテージは「エッジ」にあり:Vercel Edge Functions の力

Vercel Edge Functions(特に Next.js の Middleware として利用する場合)は、アプリケーションのオリジンサーバーにリクエストが到達するに、ユーザーに最も近い世界中のエッジロケーションでコードを実行する仕組みです。

この「エッジで処理する」という点が、パフォーマンスとパーソナライゼーションを両立させる鍵となります。

  • 超低遅延(Speed): 物理的にユーザーに近い場所でコードが実行されるため、レスポンスが極めて高速です。
  • パフォーマンス(Performance): レスポンスがユーザーに届く前にHTMLを書き換えたり、リクエストを別のページに振り分けたりできます。これにより、クライアントサイドでのDOM操作が不要になり、CLSの発生を根本から防ぎます。
  • 柔軟性(Flexibility): リクエストヘッダーの情報を元に認証を行ったり、ユーザーの地域によって表示言語を変えたりと、様々なロジックを実装できます。

リアルタイム制御を担う:LaunchDarkly のターゲティング能力

LaunchDarkly は、単なる機能の ON/OFF を切り替えるツールではありません。その本質は、強力なユーザー ターゲティング エンジンにあります。

  • リアルタイムなセグメンテーション: 管理画面から数クリックするだけで、「誰に」「何を」見せるかをリアルタイムに変更できます。コードのデプロイは一切不要です。
  • リッチなユーザー コンテキスト: 地域、使用デバイス、料金プラン、アプリ内での行動履歴など、あらゆるユーザー属性をターゲティングのルールとして利用できます。
  • パフォーマンス重視の SDK: LaunchDarkly の SDK は、エッジのような低遅延が求められる環境でも、フラグの評価が超高速(通常 1ミリ秒未満)で行えるよう最適化されています。

Vercel/Next.js 環境における LaunchDarkly リリース戦略の実装 

単に Vercel と Next.js を使っているだけでは、複雑なリリースの課題が自然と解決するわけではありません。LaunchDarkly は、そのための「制御レイヤー」としての役割を果たします。ここでは、LaunchDarkly の主要な戦略を実装するための、より具体的なステップを見ていきましょう。

アーキテクチャ概要:3つの技術の連携フロー

今回実装するエッジ・パーソナライゼーションの仕組みは、以下の流れで動作します。

  1. ユーザーが Vercel 上の Next.js サイトにアクセスします。
  2. リクエストはまず Vercel Edge Middleware に到達します。
  3. Middleware がリクエスト情報(クッキーなど)からユーザーを識別します。
  4. 識別したユーザー情報(コンテキスト)を LaunchDarkly SDK に渡して、パーソナライゼーション用のフラグを評価します。
  5. LaunchDarkly から返された結果(例:「プレミアム会員向けバナーを表示」)に基づき、Middleware がリクエストを書き換え、別のページを表示するように内部的に振り分けます。
  6. 最終的に、ユーザーには最初からパーソナライズされた HTML が配信されます。

実装解説:パーソナライズされたヒーロー バナーを出し分ける

それでは、具体的な実装を見ていきましょう。
シナリオ: EC サイトのトップページで、プレミアム会員にだけ特別なヒーロー バナーを表示する。

Step 1: LaunchDarkly でフィーチャー フラグを作成

まず、LaunchDarklyの管理画面で、文字列(String)型の多変量フラグを作成します。

  1. フラグ名: hero-banner-variation
  2. Variations (選択肢):
    • default: 通常ユーザー向け
    • premium: プレミアム会員向け
    • new-user: 新規登録ユーザー向け

次に、ターゲティングルールを設定します。「もしユーザー属性 planpremium ならば、premium variation を返す」というルールを追加します。

Step 2: Next.js Middleware (middleware.ts) を作成

Next.js プロジェクトのルートに middleware.ts ファイルを作成し、以下のコードを記述します。

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { init } from '@launchdarkly/vercel-server-sdk';

// LaunchDarkly Vercel SDKを初期化
const ldClient = init(process.env.LD_SDK_KEY || '');

export async function middleware(request: NextRequest) {
  // ユーザーを一意に識別するキーを取得 (例: クッキーやJWTから)
  const userKey = request.cookies.get('user_key')?.value || 'anonymous';
  // ユーザーのプラン情報を取得
  const userPlan = request.cookies.get('user_plan')?.value || 'default';

  // LaunchDarklyに渡すユーザーコンテキストを作成
  const context = {
    kind: 'user',
    key: userKey,
    custom: {
      plan: userPlan,
    },
  };

  // フラグを評価
  const bannerVariation = await ldClient.variation('hero-banner-variation', context, 'default');
  
  const url = request.nextUrl;
  
  // フラグの結果に応じてURLを書き換え
  url.pathname = `/banners/${bannerVariation}`;
  
  // 内部的にリクエストを書き換えて、対応するページを表示
  return NextResponse.rewrite(url);
}

// Middlewareを実行するパスを指定
export const config = {
  matcher: '/',
};

ポイント:

  • NextResponse.rewrite() を使うことで、ユーザーのブラウザ URL は / のまま、サーバー内部では /banners/premium/banners/default のような別のパスに対応するページをレンダリングさせることができます。
  • @launchdarkly/vercel-server-sdk を利用することで、Vercel Edge 環境に最適化された形で LaunchDarkly を簡単に利用できます。
Step 3: Next.js で各バリエーションのページを作成

Next.js 13 以降の App Router では、Intercepting RoutesParallel Routes といった機能を使うと、この種の出し分けを非常にクリーンに実装できます。今回はシンプルなフォルダ構成で実装します。
app/banners/[variation]/page.tsx という構造でファイルを作成します。

import PremiumHero from '@/components/PremiumHero';
import RegularContent from '@/components/RegularContent';

export default function PremiumHomePage() {
  return (
    <main>
      <PremiumHero />
      <RegularContent />
    </main>
  );
}
import DefaultHero from '@/components/DefaultHero';
import RegularContent from '@/components/RegularContent';

export default function DefaultHomePage() {
  return (
    <main>
      <DefaultHero />
      <RegularContent />
    </main>
  );
}

これで、Middleware がリクエストを書き換えることで、ユーザーには出し分けられたヒーロー バナーを含むページが最初から表示されます。クライアント サイドでのちらつきは一切ありません。

パフォーマンスへの影響は?

「エッジで SDK を呼び出すと、その分遅延が発生するのでは?」と懸念されるかもしれません。 LaunchDarkly のアーキテクチャはパフォーマンスを最優先に設計されており、SDK が一度初期化されると、フラグのルール セットはメモリ上に保持されます。そのため、2回目以降のフラグ評価はネットワーク通信を発生させずにミリ秒未満で完了します。これは、パーソナライゼーションのためにクライアント サイドで API を呼び出し、その結果を待ってから DOM を書き換える手法に比べて、圧倒的に高速かつ優れたユーザー体験を提供します。

光の速さで行われるパーソナライゼーション

まとめ

Next.js、Vercel Edge Functions、そして LaunchDarkly。これら3つの強力な技術を組み合わせることで、私たちは「パフォーマンスか、パーソナライゼーションか」という長年のトレードオフから解放されます。

ユーザーに最適化されたコンテンツを、最高のパフォーマンスで届ける。この「エッジ・パーソナライゼーション」は、これからのウェブ開発における新たなスタンダードとなるでしょう。ぜひ、LaunchDarkly を活用して、あなたのプロダクトのユーザー体験を次のレベルへと引き上げてください。

エクセルソフト株式会社は、LaunchDarkly の正式代理店として、日本のお客様の導入と活用を強力にサポートしております。

また、LaunchDarkly のすべての機能をご体験いただける体験版のご登録も代行いたします。まずはその効果を実感していただくことが、導入への第一歩だと考えております。LaunchDarkly の導入をご検討の際は、ぜひエクセルソフト株式会社にお任せください。お客様のビジネス成長に貢献できるよう、全力でサポートさせていただきます。

お見積りは無料です。どうぞお気軽にお問い合わせください。

LaunchDarkly に関する情報、お問い合わせはこちらから

出典

Vercel & Next.js 公式ドキュメント

  • Vercel Functions Documentation
    • https://vercel.com/docs/functions
      Vercel Functions(Edge Functionsを含む)の公式ドキュメントです。機能の概要、設定方法、APIリファレンスなどが網羅されています。
  • Next.js Middleware
  • Next.js Parallel Routes
    • https://nextjs.org/docs/app/api-reference/file-conventions/parallel-routes
      ブログの実装例で触れた、より高度な UI パターンを実現するための Next.js の機能です。同じレイアウト内で複数のページを同時に、または条件付きでレンダリングする方法が解説されており、パーソナライズされたコンポーネントの出し分けに応用できます。

LaunchDarkly 公式ドキュメント

パーソナライゼーションの制御を担う LaunchDarkly の公式情報です。特に Vercel 環境に特化した SDK の情報です。

  • LaunchDarkly Vercel SDK Reference
    • https://launchdarkly.com/docs/sdk/edge/vercel
      今回の記事で利用した @launchdarkly/vercel-server-sdk の公式リファレンスです。Vercel Edge 環境でLaunchDarkly を初期化し、フィーチャーフラグを評価する方法が解説されています。
  • npm: @launchdarkly/vercel-server-sdk

関連コンセプトに関する参考サイト

  • Personalization strategies that power ecommerce growth (Vercel Blog)
  • Cumulative Layout Shift (CLS) | web.dev
    • https://web.dev/articles/cls
      Google が提供するウェブ開発者向けサイトの記事です。今回のブログで解決を目指したパフォーマンス指標の一つ、CLS(Cumulative Layout Shift)が何であるか、なぜ重要なのか、どのように計算されるのかが詳細に解説されています。

*本記事に掲載されている情報は、執筆時点(2025年 7月 3日)のものです。製品の仕様や各種サービスの内容は、予告なく変更される場合がありますので、最新の情報は公式サイト等でご確認ください。

本ブログ記事の著作権は、エクセルソフト株式会社に帰属します。記事の内容、テキスト、画像等の無断転載・複製を固く禁じます。

本ブログ記事に掲載された内容によって生じたいかなる損害についても、当方では一切の責任を負いかねます。また、本ブログからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等についても一切の責任を負いません。あらかじめご了承ください。

タイトルとURLをコピーしました