StartupKitstartupkit
Analytics

Feature Flags

How to use feature flags with @repo/analytics

Control feature rollouts and run experiments with feature flags. Flags are passed through the AnalyticsProvider and accessible via hooks.

Setup

1. Fetch Flags Server-Side

app/layout.tsx
import type {  } from "react"
import {  } from "@repo/analytics/server"
import {  } from "@/lib/auth"
import {  } from "next/headers"
import {  } from "./providers"

export default async function ({  }: { :  }) {
  const  = await .api.getSession({ : await () })
  const  = ?.user?.id
  const  = await ()

  return (
    <>
      <>
        < ={}>
          {}
        </>
      </>
    </>
  )
}

2. Pass to Provider

app/providers.tsx
"use client"

import {  } from "@repo/analytics"
import {  } from "@/lib/analytics"

export function ({ ,  }) {
  return (
    < ={} ={}>
      {}
    </>
  )
}

Using Flags

useFlag Hook

Check a single flag:

"use client"

import {  } from "@repo/analytics"

export function () {
  const  = ("new-dashboard")

  if (!) return null

  return <>Welcome to the new dashboard!</>
}

useAnalytics Hook

Access all flags at once:

"use client"

import {  } from "@repo/analytics"

export function () {
  const {  } = ()

  return (
    <>
      {["feature-a"] && <FeatureA />}
      {["feature-b"] && <FeatureB />}
    </>
  )
}

Flag Types

Flags can be boolean or string values:

interface Flags {
  "new-dashboard": boolean       // On/off
  "pricing-variant": "A" | "B"   // A/B test
  "api-version": "v1" | "v2"     // Gradual rollout
}

Boolean Flags

const  = ("show-banner")

if () {
  return <Banner />
}

String/Variant Flags

const  = ("checkout-variant")

switch () {
  case "A":
    return <CheckoutA />
  case "B":
    return <CheckoutB />
  default:
    return <CheckoutDefault />
}

Server-Side Flag Checks

Check flags in Server Components or API routes:

app/dashboard/page.tsx
import {  } from "@repo/analytics/server"
import {  } from "@/lib/auth"
import {  } from "next/headers"

export default async function () {
  const  = await .api.getSession({ : await () })
  const  = await (?.user?.id)

  if (["new-dashboard"]) {
    return <NewDashboard />
  }

  return <LegacyDashboard />
}

Type Safety

Define your flags for better TypeScript support:

types/flags.ts
export interface Flags {
  "new-dashboard": boolean
  "dark-mode": boolean
  "checkout-variant": "control" | "variant-a" | "variant-b"
}

Then use with the hook:

import {  } from "@repo/analytics"
import type {  } from "@/types/flags"

export function () {
  const {  } = () as { :  }

  // TypeScript knows the flag types
  if (["new-dashboard"]) {
    // ...
  }
}

Common Patterns

Gradual Rollout

Roll out a feature to a percentage of users:

// In PostHog, set "new-feature" to 10% rollout
const  = ("new-feature")

return  ? <NewFeature /> : <OldFeature />

Beta Access

Gate features for beta users:

const  = ("beta-access")

if () {
  return (
    <>
      <BetaBadge />
      <BetaFeatures />
    </>
  )
}

A/B Testing

Run experiments:

"use client"

import {  } from "react"
import { ,  } from "@repo/analytics"

function () {
  const  = ("pricing-experiment")
  const {  } = ()

  (() => {
    ("EXPERIMENT_VIEWED", {
      : "pricing-experiment",
      
    })
  }, [, ])

  return  === "A" ? <PricingA /> : <PricingB />
}

Kill Switch

Disable a feature instantly:

const  = ("feature-x-enabled")

if (!) {
  return <MaintenanceMessage />
}

return <FeatureX />

Fallback Values

When flags are loading or unavailable:

const  = ("new-feature")

// isEnabled is null if flags haven't loaded
if ( === null) {
  return <LoadingState />
}

if () {
  return <NewFeature />
}

return <DefaultFeature />

PostHog Integration

If using PostHog, flags are fetched automatically:

lib/analytics-server.ts
import {  } from "posthog-node"

const  = new (..!)

export async function (?: string) {
  if (!) return {}
  
  const  = await .getAllFlags()
  return 
}

See the PostHog documentation for full configuration.

Next Steps

On this page