Next.js Supabase V3 (#463)
Version 3 of the kit: - Radix UI replaced with Base UI (using the Shadcn UI patterns) - next-intl replaces react-i18next - enhanceAction deprecated; usage moved to next-safe-action - main layout now wrapped with [locale] path segment - Teams only mode - Layout updates - Zod v4 - Next.js 16.2 - Typescript 6 - All other dependencies updated - Removed deprecated Edge CSRF - Dynamic Github Action runner
This commit is contained in:
committed by
GitHub
parent
4912e402a3
commit
7ebff31475
260
docs/configuration/feature-flags-configuration.mdoc
Normal file
260
docs/configuration/feature-flags-configuration.mdoc
Normal file
@@ -0,0 +1,260 @@
|
||||
---
|
||||
status: "published"
|
||||
label: "Feature Flags"
|
||||
title: "Feature Flags Configuration in the Next.js Supabase SaaS Kit"
|
||||
description: "Enable or disable team accounts, billing, notifications, and theme toggling in the Next.js Supabase SaaS Kit using feature flags."
|
||||
order: 4
|
||||
---
|
||||
|
||||
The feature flags configuration at `apps/web/config/feature-flags.config.ts` controls which features are enabled in your application. Toggle team accounts, billing, notifications, and more using environment variables.
|
||||
|
||||
{% alert type="default" title="Feature Flags vs Configuration" %}
|
||||
Feature flags control whether functionality is available to users. Use them to ship different product tiers, run A/B tests, or disable features during maintenance. Unlike configuration, feature flags are meant to change at runtime or between deployments.
|
||||
{% /alert %}
|
||||
|
||||
{% alert type="warning" title="Defaults Note" %}
|
||||
The "Default" column shows what the code uses if the environment variable is not set. The kit's `.env` file ships with different values to demonstrate features. Check your `.env` file for the actual starting values.
|
||||
{% /alert %}
|
||||
|
||||
## Available Feature Flags
|
||||
|
||||
| Flag | Environment Variable | Default | Description |
|
||||
|------|---------------------|---------|-------------|
|
||||
| Theme Toggle | `NEXT_PUBLIC_ENABLE_THEME_TOGGLE` | `true` | Allow users to switch themes |
|
||||
| Account Deletion | `NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_DELETION` | `false` | Users can delete their accounts |
|
||||
| Team Accounts | `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS` | `true` | Enable team/organization features |
|
||||
| Team Creation | `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_CREATION` | `true` | Users can create new teams |
|
||||
| Team Deletion | `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_DELETION` | `false` | Users can delete their teams |
|
||||
| Personal Billing | `NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING` | `false` | Billing for personal accounts |
|
||||
| Team Billing | `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING` | `false` | Billing for team accounts |
|
||||
| Notifications | `NEXT_PUBLIC_ENABLE_NOTIFICATIONS` | `true` | In-app notification system |
|
||||
| Realtime Notifications | `NEXT_PUBLIC_REALTIME_NOTIFICATIONS` | `false` | Live notification updates |
|
||||
| Version Updater | `NEXT_PUBLIC_ENABLE_VERSION_UPDATER` | `false` | Check for app updates |
|
||||
| Teams Only | `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_ONLY` | `false` | Skip personal accounts, use teams only |
|
||||
| Language Priority | `NEXT_PUBLIC_LANGUAGE_PRIORITY` | `application` | User vs app language preference |
|
||||
|
||||
## Common Configurations
|
||||
|
||||
### B2C SaaS (Personal Accounts Only)
|
||||
|
||||
For consumer applications where each user has their own account and subscription:
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS=false
|
||||
NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING=true
|
||||
NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_DELETION=true
|
||||
```
|
||||
|
||||
### B2B SaaS (Team Accounts Only)
|
||||
|
||||
For business applications where organizations subscribe and manage team members. Enable `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_ONLY` to skip personal accounts entirely:
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS=true
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_ONLY=true
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING=true
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_DELETION=true
|
||||
NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING=false
|
||||
```
|
||||
|
||||
When `NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_ONLY=true`:
|
||||
|
||||
- Users are automatically redirected away from personal account routes to their team workspace
|
||||
- The personal account section in the sidebar/workspace switcher is hidden
|
||||
- After sign-in, users land on their team dashboard instead of a personal home page
|
||||
- The last selected team is remembered in a cookie so returning users go straight to their team
|
||||
|
||||
This is the recommended approach for B2B apps. It removes the personal account layer entirely so users only interact with team workspaces.
|
||||
|
||||
### Hybrid Model (Both Personal and Team)
|
||||
|
||||
For applications supporting both individual users and teams (uncommon):
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS=true
|
||||
NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING=true
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING=true
|
||||
```
|
||||
|
||||
### Managed Onboarding (No Self-Service Team Creation)
|
||||
|
||||
For applications where you create teams on behalf of customers:
|
||||
|
||||
```bash
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS=true
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_CREATION=false
|
||||
NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING=true
|
||||
```
|
||||
|
||||
## Decision Matrix
|
||||
|
||||
Use this matrix to decide which flags to enable:
|
||||
|
||||
| Use Case | Theme | Teams | Team Creation | Personal Billing | Team Billing | Deletion |
|
||||
|----------|-------|-------|---------------|------------------|--------------|----------|
|
||||
| B2C Consumer App | Yes | No | - | Yes | - | Yes |
|
||||
| B2B Team SaaS | Optional | Yes | Yes | No | Yes | Optional |
|
||||
| Enterprise SaaS | Optional | Yes | No | No | Yes | No |
|
||||
| Freemium Personal | Yes | No | - | Yes | - | Yes |
|
||||
| Marketplace | Optional | Yes | Yes | Yes | No | Yes |
|
||||
|
||||
## How It Works
|
||||
|
||||
The configuration file parses environment variables with sensible defaults:
|
||||
|
||||
```typescript
|
||||
const featuresFlagConfig = FeatureFlagsSchema.parse({
|
||||
enableThemeToggle: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_THEME_TOGGLE,
|
||||
true,
|
||||
),
|
||||
enableAccountDeletion: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_DELETION,
|
||||
false,
|
||||
),
|
||||
enableTeamDeletion: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_DELETION,
|
||||
false,
|
||||
),
|
||||
enableTeamAccounts: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS,
|
||||
true,
|
||||
),
|
||||
enableTeamCreation: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_CREATION,
|
||||
true,
|
||||
),
|
||||
enablePersonalAccountBilling: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_PERSONAL_ACCOUNT_BILLING,
|
||||
false,
|
||||
),
|
||||
enableTeamAccountBilling: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_TEAM_ACCOUNTS_BILLING,
|
||||
false,
|
||||
),
|
||||
languagePriority: process.env.NEXT_PUBLIC_LANGUAGE_PRIORITY,
|
||||
enableNotifications: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_NOTIFICATIONS,
|
||||
true,
|
||||
),
|
||||
realtimeNotifications: getBoolean(
|
||||
process.env.NEXT_PUBLIC_REALTIME_NOTIFICATIONS,
|
||||
false,
|
||||
),
|
||||
enableVersionUpdater: getBoolean(
|
||||
process.env.NEXT_PUBLIC_ENABLE_VERSION_UPDATER,
|
||||
false,
|
||||
),
|
||||
});
|
||||
```
|
||||
|
||||
## Using Feature Flags in Code
|
||||
|
||||
### In Server Components
|
||||
|
||||
```typescript
|
||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
||||
|
||||
export default function SettingsPage() {
|
||||
return (
|
||||
<div>
|
||||
{featureFlagsConfig.enableTeamAccounts && (
|
||||
<TeamAccountsSection />
|
||||
)}
|
||||
{featureFlagsConfig.enableAccountDeletion && (
|
||||
<DeleteAccountButton />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### In Client Components
|
||||
|
||||
```tsx
|
||||
'use client';
|
||||
|
||||
import featureFlagsConfig from '~/config/feature-flags.config';
|
||||
|
||||
export function ThemeToggle() {
|
||||
if (!featureFlagsConfig.enableThemeToggle) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <ThemeSwitch />;
|
||||
}
|
||||
```
|
||||
|
||||
### Conditional Navigation
|
||||
|
||||
The navigation configuration files already use feature flags:
|
||||
|
||||
```typescript
|
||||
// From personal-account-navigation.config.tsx
|
||||
featureFlagsConfig.enablePersonalAccountBilling
|
||||
? {
|
||||
label: 'common.routes.billing',
|
||||
path: pathsConfig.app.personalAccountBilling,
|
||||
Icon: <CreditCard className={iconClasses} />,
|
||||
}
|
||||
: undefined,
|
||||
```
|
||||
|
||||
## Feature Flag Details
|
||||
|
||||
### Theme Toggle
|
||||
|
||||
Controls whether users can switch between light and dark themes. When disabled, the app uses `NEXT_PUBLIC_DEFAULT_THEME_MODE` exclusively.
|
||||
|
||||
### Account Deletion
|
||||
|
||||
Allows users to permanently delete their personal accounts. Disabled by default to prevent accidental data loss. Consider enabling for GDPR compliance.
|
||||
|
||||
### Team Accounts
|
||||
|
||||
Master switch for all team functionality. When disabled, the application operates in personal-account-only mode. Disabling this also hides team-related navigation and features.
|
||||
|
||||
### Team Creation
|
||||
|
||||
Controls whether users can create new teams. Set to `false` for enterprise scenarios where you provision teams manually.
|
||||
|
||||
### Team Deletion
|
||||
|
||||
Allows team owners to delete their teams. Disabled by default to prevent accidental data loss.
|
||||
|
||||
### Personal vs Team Billing
|
||||
|
||||
Choose one based on your business model:
|
||||
|
||||
- **Personal billing**: Each user subscribes individually (B2C)
|
||||
- **Team billing**: Organizations subscribe and add team members (B2B)
|
||||
|
||||
Enabling both is possible but uncommon. Most SaaS applications use one model.
|
||||
|
||||
### Notifications
|
||||
|
||||
Enables the in-app notification system. When combined with `realtimeNotifications`, notifications appear instantly via Supabase Realtime.
|
||||
|
||||
### Language Priority
|
||||
|
||||
Controls language selection behavior:
|
||||
|
||||
- `application`: Use the app's default locale
|
||||
- `user`: Respect the user's browser language preference
|
||||
|
||||
### Version Updater
|
||||
|
||||
When enabled, the app checks for updates and notifies users. Useful for deployed applications that receive frequent updates.
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Enabling both billing modes**: While technically possible, enabling both personal and team billing may create confusing user experience (unless your business model is a hybrid of both). Choose one model.
|
||||
2. **Disabling teams after launch**: If you've collected team data and then disable teams, users lose access. Plan your model before launch.
|
||||
3. **Forgetting deletion flows**: If you enable deletion, ensure you also handle cascading data deletion and GDPR compliance.
|
||||
4. **Realtime without base notifications**: `realtimeNotifications` requires `enableNotifications` to be true. The realtime flag adds live updates, not the notification system itself.
|
||||
|
||||
## Related Topics
|
||||
|
||||
- [Application Configuration](/docs/next-supabase-turbo/configuration/application-configuration) - Core app settings
|
||||
- [Environment Variables](/docs/next-supabase-turbo/configuration/environment-variables) - Complete variable reference
|
||||
- [Navigation Configuration](/docs/next-supabase-turbo/configuration/personal-account-sidebar-configuration) - Sidebar customization
|
||||
Reference in New Issue
Block a user