Skip to Content
ClientConfiguration

Configuration

The Fast Forward Dev client uses a centralized configuration system located in /src/config/config.ts. This file controls environment detection, product types, backend connectivity, theming, and Stripe integration.

Main Configuration File

Location

src/config/config.ts

Overview

The configuration file exports:

  • isProd() - Environment detection function
  • ProductType - Enum for Stripe product types
  • appConfig - Main configuration object

Environment Detection

isProd() Function

config.ts
export const isProd = () => process.env.NODE_ENV === 'production'

This utility function determines if the application is running in production mode. It’s used throughout the app to switch between development and production settings.

Usage:

import { isProd } from '@/config/config' if (isProd()) { // Use production settings } else { // Use development settings }

Product Types

ProductType Enum

config.ts
export enum ProductType { BASIC = 'basic', PRO = 'pro', }

This enum defines the available product tiers for your application. You can add more tiers as needed.

Adding a New Product Type:

export enum ProductType { BASIC = 'basic', PRO = 'pro', ENTERPRISE = 'enterprise', // New tier }

When adding new product types, you must also add corresponding Stripe price IDs in the configuration below.

Main Configuration Object

appConfig Structure

config.ts
export const appConfig = { nextConfig: { backendUrl: string, theme: string, }, siteName: string, stripe: { publicKey: string, priceIds: Record<ProductType, string>, }, }

Next.js Configuration

Backend URL

config.ts
nextConfig: { backendUrl: isProd() ? 'https://fast-forward-dev-6564a4547efb.herokuapp.com' : 'http://localhost:5001', }

Controls which backend server the client connects to.

Development:

  • Points to http://localhost:5001
  • Your local Express server

Production:

  • Points to your deployed backend
  • Update this URL after deploying your server

Customization:

backendUrl: isProd() ? 'https://your-production-backend.com' // Your production URL : 'http://localhost:5001',

If you change the local port, update both the backend .env file and this configuration.

Theme

config.ts
nextConfig: { theme: 'ffd', }

Specifies which DaisyUI theme to use. The ‘ffd’ theme is a custom theme defined in src/app/globals.css using Tailwind CSS v4 syntax.

Available Options:

  • 'ffd' - Custom Fast Forward Dev theme (default)
  • Any DaisyUI theme  (e.g., ‘light’, ‘dark’, ‘cupcake’, ‘corporate’)

The FFD Theme:

The custom FFD theme is defined in src/app/globals.css:

globals.css
@plugin "daisyui/theme" { name: "ffd"; default: true; prefersdark: false; color-scheme: "light"; /* Primary - Bright blue #007dff */ --color-primary: oklch(60% 0.22 250); --color-primary-content: oklch(99% 0 0); /* Secondary - Muted green #5d8562 */ --color-secondary: oklch(55% 0.06 150); --color-secondary-content: oklch(100% 0 0); /* ... more colors */ }

Customization:

To change the theme to a DaisyUI preset:

config.ts
theme: 'dark', // Use DaisyUI's dark theme

To customize the FFD theme colors, edit src/app/globals.css:

globals.css
@plugin "daisyui/theme" { name: "ffd"; --color-primary: oklch(65% 0.25 270); /* New purple color */ --color-secondary: oklch(60% 0.18 180); /* New teal color */ /* ... customize other colors */ }

Fast Forward Dev uses Tailwind CSS v4 syntax with DaisyUI. Learn more at DaisyUI Themes .

Site Name

config.ts
siteName: 'Fast Forward Dev',

The name of your application. Used in:

  • Page titles
  • Meta tags
  • Email templates
  • Footer

Customization:

siteName: 'My Awesome App',

After changing the site name, update it in other places like layout.tsx metadata and email templates.

Stripe Configuration

Public Key

config.ts
stripe: { publicKey: isProd() ? process.env.PUBLIC_STRIPE_PUBLISHABLE_KEY : process.env.PUBLIC_TEST_STRIPE_PUBLISHABLE_KEY, }

Automatically selects the correct Stripe publishable key based on environment.

Development:

  • Uses PUBLIC_TEST_STRIPE_PUBLISHABLE_KEY from .env.local
  • Test mode key (starts with pk_test_)

Production:

  • Uses PUBLIC_STRIPE_PUBLISHABLE_KEY from .env.local
  • Live mode key (starts with pk_live_)

Price IDs

config.ts
const productType = isProd() ? { [ProductType.BASIC]: 'price_1P3s4xP4McnT55wKrtb3OPsc', [ProductType.PRO]: 'price_1PED7uP4McnT55wKre6G3Rjd', } : { [ProductType.BASIC]: 'price_1SahUM1DJWXEccvOnwl9U0g7', [ProductType.PRO]: 'price_1SahiD1DJWXEccvOkfp8zjKQ', } stripe: { priceIds: productType, }

Maps product types to Stripe price IDs. Separate IDs for test and production modes.

Getting Price IDs:

  1. Go to Stripe Dashboard 
  2. Navigate to “Products”
  3. Create or select a product
  4. Create a price (one-time or recurring)
  5. Copy the price ID (starts with price_)

Customization:

const productType = isProd() ? { [ProductType.BASIC]: 'price_live_basic_id', [ProductType.PRO]: 'price_live_pro_id', [ProductType.ENTERPRISE]: 'price_live_enterprise_id', // New tier } : { [ProductType.BASIC]: 'price_test_basic_id', [ProductType.PRO]: 'price_test_pro_id', [ProductType.ENTERPRISE]: 'price_test_enterprise_id', // New tier }

Always create separate test and production prices in Stripe. Never use production price IDs in development.

Using Configuration in Your App

Importing

import { appConfig, isProd, ProductType } from '@/config/config'

Accessing Values

// Get backend URL const backendUrl = appConfig.nextConfig.backendUrl // Get site name const siteName = appConfig.siteName // Get Stripe public key const stripeKey = appConfig.stripe.publicKey // Get price ID for a specific product const basicPriceId = appConfig.stripe.priceIds[ProductType.BASIC]

Example: Making API Calls

import { appConfig } from '@/config/config' async function fetchUser() { const response = await fetch(`${appConfig.nextConfig.backendUrl}/api/user`, { headers: { 'Authorization': `Bearer ${token}`, }, }) return response.json() }

Example: Stripe Checkout

import { appConfig, ProductType } from '@/config/config' import { loadStripe } from '@stripe/stripe-js' const stripe = await loadStripe(appConfig.stripe.publicKey!) const { error } = await stripe.redirectToCheckout({ lineItems: [{ price: appConfig.stripe.priceIds[ProductType.PRO], quantity: 1, }], mode: 'payment', successUrl: `${window.location.origin}/thank-you`, cancelUrl: `${window.location.origin}/pricing`, })

Stripe Configuration File

Location

src/config/stripe.ts

Purpose

Initializes the Stripe SDK for server-side operations (API routes).

stripe.ts
import Stripe from 'stripe' const stripeKey = process.env.NODE_ENV === 'production' ? process.env.STRIPE_SECRET_KEY : process.env.STRIPE_TEST_SECRET_KEY const stripe = new Stripe(stripeKey, { apiVersion: '2025-11-17.clover', }) export default stripe

This file uses secret keys (not publishable keys). It should only be imported in API routes, never in client components.

Usage in API Routes

app/api/checkout_session/route.ts
import stripe from '@/config/stripe' export async function POST(req: Request) { const session = await stripe.checkout.sessions.create({ // ... session config }) return Response.json({ sessionId: session.id }) }

Complete Configuration Example

Here’s a fully customized configuration:

config.ts
export const isProd = () => process.env.NODE_ENV === 'production' export enum ProductType { STARTER = 'starter', PROFESSIONAL = 'professional', ENTERPRISE = 'enterprise', } const productType = isProd() ? { [ProductType.STARTER]: 'price_live_starter', [ProductType.PROFESSIONAL]: 'price_live_professional', [ProductType.ENTERPRISE]: 'price_live_enterprise', } : { [ProductType.STARTER]: 'price_test_starter', [ProductType.PROFESSIONAL]: 'price_test_professional', [ProductType.ENTERPRISE]: 'price_test_enterprise', } export const appConfig = { nextConfig: { backendUrl: isProd() ? 'https://api.myapp.com' : 'http://localhost:5001', theme: 'corporate', }, siteName: 'My SaaS App', stripe: { publicKey: isProd() ? process.env.PUBLIC_STRIPE_PUBLISHABLE_KEY : process.env.PUBLIC_TEST_STRIPE_PUBLISHABLE_KEY, priceIds: productType, }, }

Best Practices

Environment Variables

  • Store sensitive keys in .env.local (never commit to Git)
  • Use different keys for development and production
  • Prefix client-side variables with PUBLIC_

Configuration Updates

  • Update backendUrl after deploying your server
  • Keep price IDs in sync with Stripe Dashboard
  • Test configuration changes in development first

Type Safety

The configuration is fully typed, so TypeScript will catch errors:

// ✅ Correct const priceId = appConfig.stripe.priceIds[ProductType.BASIC] // ❌ TypeScript error - typo in ProductType const priceId = appConfig.stripe.priceIds[ProductType.BASIK]

Troubleshooting

”Cannot connect to backend” errors

  • Verify backendUrl is correct
  • Check that backend server is running
  • Ensure CORS is configured on backend

Stripe errors

  • Verify you’re using the correct keys (test vs. live)
  • Check price IDs match your Stripe Dashboard
  • Ensure public key is accessible (starts with pk_)

Theme not applying

  • Check theme name matches tailwind.config.ts
  • Verify DaisyUI is installed
  • Clear Next.js cache: rm -rf .next

Next Steps

Last updated on