価格グループ機能ガイド
機能概要
価格グループは、NEXTY.DEV ボイラープレートが提供する柔軟な価格管理機能で、カスタムグループに従って価格プランを整理および表示できます。これにより、フロントエンドページでの価格情報の表示に大きな柔軟性が提供されます。複数のページやコンポーネントで異なる方法で価格情報を表示する必要がある場合でも、簡単に実現できます。
コアの利点
- 柔軟なグループ化: カスタムグループ識別子(slug)を使用して、必要に応じて価格プランを整理
- フロントエンドの自由度が高い: グループでフィルタリングして表示し、さまざまなページレイアウトに適応
データ構造
グループテーブル(pricing_plan_groups)
グループは主キーとして slug を使用し、クエリと関連付けを簡素化します:
export const pricingPlanGroups = pgTable('pricing_plan_groups', {
slug: varchar('slug', { length: 100 }).primaryKey(),
createdAt: timestamp('created_at', { withTimezone: true })
.defaultNow()
.notNull(),
})価格プランテーブルのグループフィールド
各価格プランは groupSlug フィールドを通じてグループに関連付けられます:
// pricingPlans テーブル
groupSlug: varchar('group_slug', { length: 100 })
.references(() => pricingPlanGroups.slug, { onDelete: 'restrict' })
.default('default')
.notNull(),注意: グループは外部キー制約を使用します。グループを削除する前に、そのグループの下にあるすべての価格プランを削除する必要があります。
管理ダッシュボード操作
1. グループ管理エントリ
管理者ダッシュボードの価格管理ページ(/dashboard/prices)で、**「Manage Groups」**ボタンをクリックしてグループ管理ダイアログを開きます。
2. グループの作成
グループ管理ダイアログで:
- 入力フィールドにグループ識別子(slug)を入力
- Slug には小文字、数字、ハイフンのみを含めることができます(例:
annual、monthly、enterprise-plans) - 「+」ボタンをクリックするか、Enterキーを押してグループを作成

3. グループの削除
グループ管理ダイアログで:
- 各グループの右側に、そのグループの下にある価格プランの数が表示されます
- 関連する価格プランがないグループのみ削除できます
defaultグループはシステム予約グループであり、削除できません
4. グループリストの表示
価格プランリストページ(/dashboard/prices)のテーブルで、Group列に各価格プランが属するグループが表示され、すばやく表示およびフィルタリングできます。
価格プランにグループを割り当てる
価格プラン作成時にグループを選択
価格プラン作成フォームで、Groupフィールドにより:
- ドロップダウンリストから既存のグループを選択
- 新しいグループ識別子を直接入力してすばやく作成
価格プラン編集時にグループを変更
価格プランを編集する際、いつでもそのグループを変更でき、システムはすぐに有効になります。

フロントエンド表示コンポーネント
NEXTY.DEV は、さまざまなシナリオのニーズを満たす3つのすぐに使用できる価格表示コンポーネントを提供します:
1. PricingByGroup(推奨)
groupSlug でグループ化された価格カードを表示し、Tab切り替えをサポートします。
これは最も柔軟な表示方法で、ほとんどのSaaS製品の価格ページに適しています。
import { PricingByGroup } from "@/components/pricing";
export default function PricingPage() {
return <PricingByGroup />;
}デフォルトの動作:
groupSlugがannual、monthly、onetimeのプランをフィルタリング- Tab形式で切り替えて表示
- 年払い(annual)タブを優先的に表示
- プランがないタブを自動的に非表示
カスタムグループ表示:
カスタムグループ(basic、pro、enterprise など)を使用する場合、フロントエンドコンポーネントのロジックを変更して、グループで価格プランをフィルタリングするだけです:
// 例:カスタムグループでフィルタリング
const basicPlans = allPlans.filter((plan) => plan.groupSlug === "basic");
const proPlans = allPlans.filter((plan) => plan.groupSlug === "pro");
const enterprisePlans = allPlans.filter((plan) => plan.groupSlug === "enterprise");2. PricingAll
すべてのアクティブな価格カードを一度に表示し、グループ化しません。
価格プランが少ない、またはすべてのオプションを並べて表示する必要があるシナリオに適しています。
import { PricingAll } from "@/components/pricing";
export default function SimplePricingPage() {
return <PricingAll />;
}特徴:
isActive = trueのすべての価格プランを表示- プラン数に応じてグリッド列数を自動調整
- Tab切り替えなし、シンプルな価格表示に適しています
3. PricingByPaymentType
支払いタイプ(月払い/年払い/一回払い)で自動的にグループ化して表示します。
PricingByGroup と同様のTab切り替え体験ですが、グループ化ロジックは groupSlug ではなく、paymentType と recurringInterval フィールドに基づいています。
import { PricingByPaymentType } from "@/components/pricing";
export default function PaymentTypePricingPage() {
return <PricingByPaymentType />;
}自動分類ロジック:
- 月払い:
paymentTypeが recurring で、recurringIntervalが month/every-month - 年払い:
paymentTypeが recurring で、recurringIntervalが year/every-year - 一回払い:
paymentTypeが one_time/onetime
コンポーネント比較
| コンポーネント | グループ化の基準 | 表示方法 | 推奨シナリオ |
|---|---|---|---|
PricingByGroup | groupSlug フィールド | Tab切り替え | カスタムグループ、柔軟な表示制御 |
PricingAll | グループ化なし | すべて表示 | プランが少ない、シンプルなページ |
PricingByPaymentType | 支払いタイプフィールド | Tab切り替え | 支払いサイクルで区別して表示 |
関連ファイル
- コンポーネント:
components/pricing/PricingByGroup.tsx,PricingAll.tsx,PricingByPaymentType.tsx - Server Actions:
actions/prices/groups.ts,actions/prices/public.ts - データベーススキーマ:
lib/db/schema.ts - 型定義:
types/pricing.ts - 状態管理:
stores/pricingGroupStore.ts - 管理ページ:
app/[locale]/(protected)/dashboard/(admin)/prices/