Configuration

Learn how to configure your application for development and production environments.

Environment Variables

This template uses @t3-oss/env-nextjs for type-safe environment variables. All configuration is defined in src/env.ts.

Required Variables

These variables must be set for the application to run:

Database

DATABASE_URL="file:./local.db"

For production with Cloudflare D1:

DATABASE_URL="libsql://your-database.turso.io"
DATABASE_AUTH_TOKEN="your-auth-token"

Authentication

AUTH_SECRET="your-32-character-secret"
NEXTAUTH_URL="http://localhost:3000"

For production:

NEXTAUTH_URL="https://yourdomain.com"

Optional Variables

Stripe Integration

STRIPE_SECRET_KEY="sk_test_..."
STRIPE_WEBHOOK_SECRET="whsec_..."
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."

# Your pricing plan IDs
STRIPE_PRICE_ID_BASIC="price_..."
STRIPE_PRICE_ID_PRO="price_..."

Email Configuration

SMTP_HOST="smtp.gmail.com"
SMTP_PORT="587"
SMTP_USER="your-email@gmail.com"
SMTP_PASSWORD="your-app-password"
SMTP_FROM="noreply@yourdomain.com"

OAuth Providers

GitHub:

AUTH_GITHUB_ID="your-github-client-id"
AUTH_GITHUB_SECRET="your-github-client-secret"

Google:

AUTH_GOOGLE_ID="your-google-client-id"
AUTH_GOOGLE_SECRET="your-google-client-secret"

Analytics

PostHog:

NEXT_PUBLIC_POSTHOG_KEY="phc_..."
NEXT_PUBLIC_POSTHOG_HOST="https://app.posthog.com"

Application Settings

Site Metadata

Edit metadata in src/app/layout.tsx:

export const metadata: Metadata = {
  title: "Your App Name",
  description: "Your app description",
  icons: [{ rel: "icon", url: "/favicon.ico" }],
};

Update navigation links in src/components/site/header.tsx:

const nav = [
  { label: "Home", href: "/" },
  { label: "Docs", href: "/docs" },
  { label: "Blog", href: "/blog" },
  { label: "Pricing", href: "/pricing" },
];

Pricing Plans

Configure your pricing plans in src/app/pricing/page.tsx:

const plans = [
  {
    name: "Basic",
    price: "$9",
    interval: "month",
    features: ["Feature 1", "Feature 2"],
    stripePriceId: process.env.STRIPE_PRICE_ID_BASIC,
  },
  // ... more plans
];

Database Configuration

Schema

Your database schema is defined in src/server/db/schema.ts. To add new tables:

import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
 
export const posts = sqliteTable("posts", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  title: text("title").notNull(),
  content: text("content"),
  createdAt: integer("created_at", { mode: "timestamp" })
    .notNull()
    .default(sql`CURRENT_TIMESTAMP`),
});

Migrations

After schema changes, generate and apply migrations:

npm run db:generate
npm run db:push

Authentication Configuration

Session Strategy

Configure session settings in src/server/auth/config.ts:

export const authConfig = {
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  // ... other settings
};

OAuth Providers

Add new OAuth providers in src/server/auth/providers/:

import GitHub from "next-auth/providers/github";
 
export const githubProvider = GitHub({
  clientId: env.AUTH_GITHUB_ID,
  clientSecret: env.AUTH_GITHUB_SECRET,
});

Cloudflare Bindings

KV Namespace

Configure KV bindings in wrangler.toml:

[[kv_namespaces]]
binding = "KV"
id = "your-kv-namespace-id"

Access in your code:

const kv = getCloudflareContext().env.KV;
await kv.put("key", "value");

D1 Database

[[d1_databases]]
binding = "DB"
database_name = "your-database"
database_id = "your-database-id"

R2 Storage

[[r2_buckets]]
binding = "BUCKET"
bucket_name = "your-bucket"

Next Steps

After configuration, learn about: