Shipkit
DocsFeaturesPricing
DocsFeaturesPricing

Command Palette

Search for a command to run...

Shipkit DocumentationBuild memory optimizationDevelopment GuideEnvironment VariablesError HandlingFile StructureMiddlewareRebranding Guide

Vercel Deployment Checks

Development GuideCLIDependency UpdatesDevToolsFeature FlagsAI PromptsSetup RequirementsSupply chaintRPCWeb Workers

FeaturesAIAnalytics IntegrationAuthenticationCMSDatabaseEmailHapticsPaymentsComponent RegistryStorageUIVisual BuilderWaitlist Feature

Quick StartDeploymentEnvironment VariablesFile StructureSetup Wizard

Caching & Rate LimitingContent ManagementError HandlingMarkdown and MDXMiddlewareProxy-Safe Server ActionsRebranding GuideWebhook Security Implementation GuideMulti-Zone ArchitectureVercel Deployment

IntegrationsPayload CMSDataFast Analytics IntegrationGoogle Analytics IntegrationGoogle Tag Manager IntegrationPostHogStatSig IntegrationUmami Analytics IntegrationAuth.js IntegrationBetter AuthClerkStack Auth IntegrationSupabase Authentication IntegrationBuilder.io IntegrationPayload CMS IntegrationAWS S3 IntegrationResend Email IntegrationUpstash Redis IntegrationVercel Blob IntegrationLemon SqueezyPolarStripe

API RoutesComponentsAPI Route SnippetsAuthentication SnippetsComponent SnippetsForm Handling SnippetsSnippets Introduction

Environment Variables

Shipkit uses T3 Env for type-safe environment variable validation, ensuring runtime safety and excellent TypeScript integration.

Note Shipkit processes environment variables at build time. You may need to stop and start your dev server if hot module reloading isn't working.

Quick Setup

  1. Copy the example environment file:
cp .env.example .env.local
  1. Generate required secrets:
# Generate AUTH_SECRET
openssl rand -base64 32

Required Variables

Core Authentication

# Base URL for authentication
# In production, this will be automatically set to VERCEL_URL
AUTH_URL="http://localhost:3000"

# JWT secret for session management
# Generate with: openssl rand -base64 32
AUTH_SECRET=""

OAuth Providers (Optional)

# GitHub OAuth
AUTH_GITHUB_ID=""
AUTH_GITHUB_SECRET=""

# Discord OAuth
AUTH_DISCORD_ID=""
AUTH_DISCORD_SECRET=""

# Google OAuth
AUTH_GOOGLE_ID=""
AUTH_GOOGLE_SECRET=""

Database

# PostgreSQL connection string
DATABASE_URL="postgresql://postgres:password@localhost:5432/shipkit"

# Database prefix (defaults to "db")
DB_PREFIX="db"

External Services (Optional)

GitHub Integration

# GitHub access token for repo operations
GITHUB_ACCESS_TOKEN=""

Google Services

# Google service account credentials
GOOGLE_CLIENT_EMAIL=""
GOOGLE_PRIVATE_KEY=""

AI Services

# OpenAI API key
OPENAI_API_KEY=""

# Anthropic API key
ANTHROPIC_API_KEY=""

Payments

# LemonSqueezy credentials
LEMONSQUEEZY_API_KEY=""
LEMONSQUEEZY_STORE_ID=""

Node Environment

# Node environment (defaults to "development")
# Values: development, test, production
NODE_ENV="development"

Type Safety

Environment variables are validated using T3 Env and Zod schemas:

// src/env.ts
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";

export const env = createEnv({
  server: {
    DATABASE_URL: z.string().url().optional(),
    DB_PREFIX: z.string().default("db"),
    NODE_ENV: z.enum(["development", "test", "production"]).default("development"),

    // Auth
    AUTH_SECRET: z.string().optional(),
    AUTH_URL: z.preprocess(
      (str) => process.env.VERCEL_URL ?? str,
      process.env.VERCEL ? z.string().optional() : z.string().url().optional()
    ),
    AUTH_DISCORD_ID: z.string().optional(),
    AUTH_DISCORD_SECRET: z.string().optional(),
    AUTH_GITHUB_ID: z.string().optional(),
    AUTH_GITHUB_SECRET: z.string().optional(),
    AUTH_GOOGLE_ID: z.string().optional(),
    AUTH_GOOGLE_SECRET: z.string().optional(),

    // GitHub
    GITHUB_ACCESS_TOKEN: z.string().optional(),

    // Google
    GOOGLE_CLIENT_EMAIL: z.string().optional(),
    GOOGLE_PRIVATE_KEY: z.string().optional(),

    // AI Services
    OPENAI_API_KEY: z.string().optional(),
    ANTHROPIC_API_KEY: z.string().optional(),

    // Payments
    LEMONSQUEEZY_API_KEY: z.string().optional(),
    LEMONSQUEEZY_STORE_ID: z.string().optional(),
  },
});

Environment Management

Local Development

  1. Copy the example environment file:
cp .env.example .env.local
  1. Update variables in .env.local

Production (Vercel)

  1. Add variables through the Vercel dashboard or CLI:
vercel env add MY_VAR
  1. After adding variables, redeploy your application:
vercel --prod

Public Env Mirroring

Certain public environment variables can be set without the NEXT_PUBLIC_ prefix. During build, Shipkit mirrors these to their NEXT_PUBLIC_* equivalents so they are available on the client. For example:

STRIPE_PUBLISHABLE_KEY=pk_test_your_key
# becomes available to the client as
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your_key

Supported base keys:

  • BUILDER_API_KEY → NEXT_PUBLIC_BUILDER_API_KEY
  • CLERK_PUBLISHABLE_KEY → NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
  • SUPABASE_URL → NEXT_PUBLIC_SUPABASE_URL
  • SUPABASE_ANON_KEY → NEXT_PUBLIC_SUPABASE_ANON_KEY
  • STRIPE_PUBLISHABLE_KEY → NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
  • POSTHOG_KEY → NEXT_PUBLIC_POSTHOG_KEY
  • UMAMI_WEBSITE_ID → NEXT_PUBLIC_UMAMI_WEBSITE_ID
  • STATSIG_CLIENT_KEY → NEXT_PUBLIC_STATSIG_CLIENT_KEY
  • GOOGLE_ANALYTICS_ID → NEXT_PUBLIC_GOOGLE_ANALYTICS_ID
  • GOOGLE_GTM_ID → NEXT_PUBLIC_GOOGLE_GTM_ID
  • C15T_URL → NEXT_PUBLIC_C15T_URL

Notes:

  • If you explicitly set a NEXT_PUBLIC_* value, it takes precedence.
  • The non-prefixed names are not exposed to the client; only the generated NEXT_PUBLIC_* values are.