Unleash + Next.jsでフィーチャーフラグを実装する
以前の記事でバックエンドのUnleashを使ってフィーチャーフラグを実装しました。今回はフロントエンドのNext.jsでUnleashを使ってフィーチャーフラグを実装する方法を紹介します。
Next.jsのプロジェクトを作成
まずはNext.jsのプロジェクトを作成します。
$ npx create-next-app@latest --ts
Need to install the following packages:
create-next-app@15.1.0
Ok to proceed? (y) y
✔ What is your project named? … unleash-client-demo
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for `next dev`? … Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No
ブラウザで http://localhost:3000
にアクセスします。以下のデフォルト画面が表示されます。
UnleashをローカルPCでセットアップ
UnleashのサーバをローカルPCでセットアップします。(本記事での方法はローカルPC上での動作確認のための方法であり、デフォルトのパスワードを使用するなどのセキュリティ上の問題があります。本番環境で使用する場合は別の方法でセットアップするようにしてください。)
Unleashサーバの起動
UnleashのサーバはDockerイメージとして提供されているので、Dockerを使ってローカルPC上で起動させます。適切なディレクトリ上で、以下のようにUnleashサーバを起動します。
wget https://raw.githubusercontent.com/Unleash/unleash/refs/heads/main/docker-compose.yml
docker compose up -d
管理画面へのサインイン
ブラウザで http://localhost:4242
にアクセスします。以下のサインイン画面が表示されます。以下の認証情報を入力してSign in
ボタンをクリックします。
User name: admin
Password: unleash4all
フィーチャーフラグの作成
左上のメニューから Projects
を選択します。
Default
プロジェクトを選択します。
Create flag
ボタンをクリックします。
Feature flag name
、Description
にフラグの名前と説明を入力し Create feature flag
ボタンをクリックします。本記事ではタスク管理サービスで締め切り日時の管理機能の追加を例に解説するので名前を support-due-date-time-frontend
としました。
トークンの発行
Connect SDK
ボタンをクリックします。
Client side SDKs
のReact
を選択します。
Enviroment
を選択して、Next
ボタンをクリックします。今回はローカルPCで動かすだけなのでdevelopment
を選択しています。
接続のための設定が表示され、クライアントからの接続待ち状態になります。
フィーチャーフラグを使ったWeb画面の実装
タスク管理アプリのAPIサーバで、フィーチャーフラグが有効になるとレスポンスに締め切り日時が表示されるケースを考えてみます。
締め切り機能追加前の状態を実装
まずは締め切り機能が追加されていない状態を実装します。
Todoの型を定義します。
export type Todo = {
id: string;
title: string;
description: string;
};
Todoのコンポーネントを作成します。
import { Todo } from "./Todo";
export const TodoComponent = (todo: Todo) => {
return (
<li key={todo.id}>
<h2 className='text-lg font-bold'>{todo.title}</h2>
<p>{todo.description}</p>
</li>
)
};
page.tsxを以下のように修正します。
'use client'
import { Todo } from "./Todo";
const unleashConfig = {
url: 'http://localhost:4242/api/frontend/',
clientKey: 'default:development.unleash-insecure-frontend-api-token',
appName: 'unleash-onboarding-react'
}
const todos: Todo[] = [
{
id: '1',
title: 'Learn Next.js',
description: 'Learn Next.js and build something great',
dueDate: '2025-01-01'
},
{
id: '2',
title: 'Build something great',
description: 'Learn Next.js and build something great',
dueDate: '2025-01-02'
}
]
export default function Home() {
return (
<FlagProvider config={unleashConfig}>
<div className='container mx-auto p-4'>
<h1 className='text-3xl font-bold mb-4'>Todo</h1>
<ul className='list-disc'>
{todos.map(todo => (
<TodoComponent key={todo.id} {...todo} />
))}
</ul>
</div>
</FlagProvider>
);
}
ブラウザには以下のように表示されます。
フィーチャーフラグを使った締め切り機能の追加
Todoの型をdueDate
を追加します。
export type Todo = {
id: string;
title: string;
description: string;
dueDate?: string;
};
Todoのコンポーネントを修正します。
import { useEffect } from "react";
import { useFlag } from "@unleash/proxy-client-react";
import { Todo } from "./Todo";
export const TodoComponent = (todo: Todo) => {
const hasVisited =
typeof window !== "undefined" && !!localStorage.getItem("hasVisited");
useEffect(() => {
if (!hasVisited) localStorage.setItem("hasVisited", "true");
}, []);
const enabled = useFlag('support-due-date-time-frontend');
return (
<li key={todo.id}>
<h2 className='text-lg font-bold'>{todo.title}</h2>
<p>{todo.description}</p>
{enabled ? <p>{todo.dueDate}</p> : null}
</li>
)
};
page.tsxを以下のように修正します。
'use client'
import dynamic from "next/dynamic";
import { FlagProvider } from "@unleash/proxy-client-react";
import { Todo } from "./Todo";
const unleashConfig = {
url: 'http://localhost:4242/api/frontend/',
clientKey: 'default:development.unleash-insecure-frontend-api-token',
appName: 'unleash-onboarding-react'
}
const TodoComponent = dynamic(() => import('./TodoComponent').then((mod) => mod.TodoComponent), {
ssr: false,
});
const todos: Todo[] = [
{
id: '1',
title: 'Learn Next.js',
description: 'Learn Next.js and build something great',
dueDate: '2025-01-01'
},
{
id: '2',
title: 'Build something great',
description: 'Learn Next.js and build something great',
dueDate: '2025-01-02'
}
]
export default function Home() {
return (
<FlagProvider config={unleashConfig}>
<div className='container mx-auto p-4'>
<h1 className='text-3xl font-bold mb-4'>Todo</h1>
<ul className='list-disc'>
{todos.map(todo => (
<TodoComponent key={todo.id} {...todo} />
))}
</ul>
</div>
</FlagProvider>
);
}
締め切りフィーチャーフラグの有効化
Unleashの管理画面で support-due-date-time-frontend
のフィーチャーフラグを develop
環境で有効化します。
ブラウザには以下のように表示されます。
Discussion