Customization Guide

Models, copy, pricing, and UI tokens live under src/config/* so you can rebrand without spelunking components.

If you ship this as a product, pair this page with the White‑Label Checklist.

Configuration Files

All business logic is controlled via config files in src/config/:

AI Models (ai-models.ts)

Add, remove, or modify AI models:

// src/config/ai-models.ts
export const AI_MODELS: Record<AIModelId, AIModelConfig> = {
  "gpt-4o-mini": {
    provider: "openai",
    costPer1kTokens: 1,
    maxTokens: 16384,
    supportsTools: false,
    supportsRAG: true,
    displayName: "GPT-4o Mini",
    friendlyName: "Fast (GPT-4o Mini)",
    description: "Quick responses, lowest cost",
  },
  "claude-3-5-sonnet-20241022": {
    provider: "anthropic",
    costPer1kTokens: 10,
    maxTokens: 200000,
    supportsTools: true,
    supportsRAG: true,
    displayName: "Claude 3.5 Sonnet",
    friendlyName: "Smart (Claude 3.5)",
    description: "Excellent reasoning and analysis",
  },
  // ...
} as const;

Don't forget to update the AIModelId type:

export type AIModelId =
  | "gpt-4o-mini"
  | "gpt-4o"
  | "gpt-4-turbo"
  | "claude-3-5-sonnet-20241022"
  | "claude-3-opus-20240229"
  // ...

Pricing Tiers (pricing.ts)

3 places to add/remove a tier:

  1. UserTier type - Add/remove the tier key
  2. PRICING_TIERS - Add/remove the tier config (credits, models, features)
  3. PRICING_DISPLAY.monthly - Add/remove the display data (price, description, button text)

Modify credit allocations and allowed models:

export const PRICING_TIERS: Record<UserTier, PricingTier> = {
  free: {
    name: "Starter",
    monthlyCredits: 100,
    creditReset: "monthly",
    allowedModels: ["gpt-4o-mini"],
    features: ["basic_chat"],
  },
  pro: {
    name: "Professional",
    monthlyCredits: 2500,        // Change allocation
    creditReset: "monthly",
    allowedModels: [
      "gpt-4o-mini",
      "gpt-4o",
      "claude-3-5-sonnet-20241022",
    ],
    features: ["basic_chat", "rag", "multi_model", "tool_use"],
    stripePriceId: process.env.STRIPE_PRO_PRICE_ID,
    stripeOneTimePriceId: process.env.STRIPE_TOPUP_PRICE_ID,
  },
};

If you add a new paid tier, also add a matching Stripe product/price and create a new env var (e.g. STRIPE_BUSINESS_PRICE_ID) in both .env.local.example and your production environment.

Features (features.ts)

Toggle features by tier:

export const FEATURES = {
  basic_chat: { enabled: true },
  rag: { enabled: true, tiers: ["pro", "enterprise"] },
  multi_model: { enabled: true, tiers: ["pro", "enterprise"] },
  voice: { enabled: false },  // Coming soon
};

UI/Branding (brand.ts + ui/*)

The marketing site is config-driven:

  • App/company identity: src/config/brand.ts
  • Landing page copy + sections: src/config/ui/* (hero, features, FAQ, footer, etc.)

Homepage sections are wired to config (no hardcoded marketing copy in the page component):

  • Hero: src/config/ui/hero.ts
  • Hero (secondary): src/config/ui/hero2.ts
  • Chat demo: src/config/ui/chat-demo.ts
  • Features: src/config/ui/features.ts
  • Highlight tabs: src/config/ui/highlight-product.ts
  • Modules carousel: src/config/ui/most-popular-products.ts
  • Modules grid: src/config/ui/product-list.ts
  • Integrations: src/config/ui/integrations.ts and src/config/ui/integrations2.ts
  • Steps/process: src/config/ui/process.ts
  • “What you get”: src/config/ui/services.ts
  • Included guides: src/config/ui/comprehensive-services.ts
  • Stats: src/config/ui/stats.ts
  • Help center: src/config/ui/help-center.ts
  • CTA / FAQ / testimonials: src/config/ui/cta.ts, src/config/ui/faq.ts, src/config/ui/faq2.ts, src/config/ui/testimonials.ts

Example: edit the hero copy in src/config/ui/hero.ts:

export const heroConfig = {
  badge: "AI-Powered Document Analysis",
  headline: "Chat with your",
  highlightWord: "Documentation",
  subheadline: "Analyze complex PDFs and knowledge bases with RAG chat.",
  primaryCta: "Get Started",
  secondaryCta: "View Pricing",
};

RAG Pipeline (rag.ts)

Tune document processing:

export const RAG_CONFIG = {
  chunking: {
    chunkSize: 1000,      // Increase for more context
    chunkOverlap: 200,    // Increase for better continuity
  },
  retrieval: {
    defaultTopK: 5,       // More chunks = more context
  },
};

Styling

Tailwind CSS v4

Colors are defined in src/app/globals.css:

@theme {
  --color-background: oklch(100% 0 0);
  --color-foreground: oklch(10% 0 0);
  --color-primary: oklch(50% 0.2 250);
  /* Customize colors here */
}

Dark Mode

Dark mode variables:

.dark {
  --color-background: oklch(10% 0 0);
  --color-foreground: oklch(95% 0 0);
}

Components

shadcn/ui components in src/components/ui/ can be customized:

// src/components/ui/button.tsx
const buttonVariants = cva(
  "inline-flex items-center...",
  {
    variants: {
      variant: {
        default: "bg-primary...",
        // Add custom variant:
        brand: "bg-gradient-to-r from-blue-500 to-purple-500...",
      },
    },
  }
);

Adding New Pages

Dashboard Page

  1. Create src/app/(dashboard)/dashboard/new-page/page.tsx
  2. Add navigation link in layout
  3. Server Component by default
// src/app/(dashboard)/dashboard/analytics/page.tsx
import { createClient } from "@/lib/supabase/server";

export default async function AnalyticsPage() {
  const supabase = await createClient();
  // Fetch data...

  return <div>Analytics Dashboard</div>;
}

API Route

// src/app/api/analytics/route.ts
import { createClient } from "@/lib/supabase/server";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  const supabase = await createClient();
  const { data: { user } } = await supabase.auth.getUser();

  if (!user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  // Your logic...
  return NextResponse.json({ data: "..." });
}

Adding New AI Providers (Advanced)

1. Install SDK

pnpm add @ai-sdk/google

2. Create Provider

// src/lib/ai/providers.ts
import { google } from "@ai-sdk/google";

export function getModelProvider(modelId: AIModelId) {
  const config = AI_MODELS[modelId];

  switch (config.provider) {
    case "openai":
      return openai(modelId);
    case "anthropic":
      return anthropic(modelId);
    case "google":
      return google(modelId);
    default:
      throw new Error(`Unknown provider: ${config.provider}`);
  }
}

3. Add Model Config

// src/config/ai-models.ts
"gemini-pro": {
  provider: "google",
  costPer1kTokens: 2,
  // ...
}

Environment Variables

If you introduce a new provider or feature flag, add the required env vars to:

  • .env.local.example (so new users know what to set)
  • Your hosting provider environment variables (production)

Tip: update the setup checklist at src/app/(dashboard)/dashboard/setup/page.tsx so buyers can quickly validate their configuration.