Skip to main content

Installation

This guide covers the complete setup of Shipr, including all required services and optional integrations. For a faster start, see the Quick Start guide.

Prerequisites

1

Node.js 18+

Download and install from nodejs.orgVerify installation:
node --version
2

pnpm package manager

Install pnpm globally:
npm install -g pnpm
Verify installation:
pnpm --version
3

Git

Ensure Git is installed for cloning the repository:
git --version

Initial Setup

1

Clone the repository

git clone <repo-url>
cd shipr
2

Install dependencies

pnpm install
This installs all packages from package.json including:
  • next (16.1.6) - Framework
  • @clerk/nextjs - Authentication
  • convex - Database and backend
  • @ai-sdk/react and ai - AI functionality
  • resend - Email sending
  • @sentry/nextjs - Error tracking
  • posthog-js - Analytics
  • UI libraries (shadcn, Tailwind, etc.)
3

Create environment file

cp .env.example .env

Configure Clerk (Required)

Clerk handles authentication, user management, and billing plan detection.
1

Create a Clerk account

  1. Visit clerk.com
  2. Sign up for a free account
  3. Create a new application
2

Configure authentication methods

In your Clerk dashboard:
  • Enable email/password authentication
  • Optionally enable social providers (Google, GitHub, etc.)
  • Configure your application name and branding
3

Copy API keys

From your Clerk dashboard, add these to .env:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
4

Set JWT issuer domain

Find your JWT issuer domain in Clerk dashboard under “API Keys”:
CLERK_JWT_ISSUER_DOMAIN=https://...clerk.accounts.dev
This must match exactly what Clerk provides, including the https:// protocol.
5

Configure redirect URLs

These are already set in .env.example:
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
You can customize these URLs if needed, but the defaults work out of the box.
6

(Optional) Enable Clerk Billing

If you want to use plan gating (Free/Pro):
  1. Enable Clerk Billing in your dashboard
  2. Configure your plans
  3. The useUserPlan hook will automatically detect the user’s plan

Configure Convex (Required)

Convex is your realtime database and backend.
1

Create a Convex account

  1. Go to convex.dev
  2. Sign up with GitHub (recommended) or email
  3. Create a new project
2

Initialize Convex

Run the Convex development server:
npx convex dev
This will:
  • Prompt you to log in if needed
  • Push your schema from convex/schema.ts
  • Generate your deployment URL
  • Start watching for changes
Keep this terminal window open during development. Convex runs alongside Next.js.
3

Copy deployment URL

After running npx convex dev, copy the URL to .env:
NEXT_PUBLIC_CONVEX_URL=https://...convex.cloud
4

Configure Clerk authentication

In the Convex dashboard:
  1. Select your project
  2. Go to Settings → Authentication
  3. Add Clerk as an authentication provider
  4. Enter your CLERK_JWT_ISSUER_DOMAIN value
This allows Convex to verify Clerk JWTs.

Set Site URL (Required)

The site URL is used for metadata, canonical URLs, sitemaps, and OG images.
# For local development
NEXT_PUBLIC_SITE_URL=http://localhost:3000

# For production (update before deploying)
NEXT_PUBLIC_SITE_URL=https://yourdomain.com

Configure Resend (Required for Email)

Resend handles transactional emails like welcome messages and plan change notifications.
1

Create a Resend account

  1. Visit resend.com
  2. Sign up for a free account
  3. You get 100 emails/day on the free tier
2

Get your API key

From the Resend dashboard:
  1. Navigate to API Keys
  2. Create a new API key
  3. Copy it to .env:
RESEND_API_KEY=re_...
3

Configure sender email

For local development/testing:
RESEND_FROM_EMAIL=[email protected]
For production with a verified domain:
RESEND_FROM_EMAIL=[email protected]
Resend’s sandbox sender works for testing, but you’ll need to verify your domain for production.
4

(Optional) Verify your domain

For production:
  1. In Resend dashboard, go to Domains
  2. Add your domain
  3. Add the DNS records Resend provides
  4. Wait for verification (usually a few minutes)

Configure AI Chat (Optional)

The AI chat feature requires Vercel AI Gateway.
1

Get AI Gateway API key

  1. Visit vercel.com
  2. Create or select a project
  3. Navigate to AI Gateway settings
  4. Generate an API key
Add to .env:
AI_GATEWAY_API_KEY=vck_...
2

Configure AI settings

Customize the AI chat behavior:
# Model to use (default: openai/gpt-4.1-mini)
AI_CHAT_MODEL=openai/gpt-4.1-mini

# System prompt
AI_CHAT_SYSTEM_PROMPT=You are Shipr's AI assistant helping builders ship SaaS faster.

# Enabled tools (comma-separated)
AI_CHAT_TOOLS=getCurrentDateTime,calculate

# Max model steps per response
AI_CHAT_MAX_STEPS=5

# Rate limiting
AI_CHAT_RATE_LIMIT_MAX_REQUESTS=20
AI_CHAT_RATE_LIMIT_WINDOW_MS=60000
3

Configure chat history

Chat history is stored in Convex:
# Enable/disable chat history
AI_CHAT_HISTORY_ENABLED=true

# Max characters per message
AI_CHAT_HISTORY_MAX_MESSAGE_LENGTH=8000

# Max messages per thread
AI_CHAT_HISTORY_MAX_MESSAGES_PER_THREAD=120

# Max threads per user
AI_CHAT_HISTORY_MAX_THREADS=50

# Max title length
AI_CHAT_HISTORY_THREAD_TITLE_MAX_LENGTH=80

# Query limit
AI_CHAT_HISTORY_QUERY_LIMIT=200
4

Configure lifetime message limits

Prevent abuse with per-user message caps:
# Enable lifetime cap (default: true for boilerplate protection)
AI_CHAT_ENFORCE_LIFETIME_MESSAGE_LIMIT=true

# Max messages per user account (default: 1)
AI_CHAT_LIFETIME_MESSAGE_LIMIT=1
Set AI_CHAT_ENFORCE_LIFETIME_MESSAGE_LIMIT=false to disable this limit for your production app.

Configure PostHog (Optional)

PostHog provides product analytics with a reverse proxy to bypass ad blockers.
1

Create a PostHog project

  1. Visit posthog.com
  2. Sign up for a free account
  3. Create a new project
2

Copy your credentials

From your PostHog project settings:
NEXT_PUBLIC_POSTHOG_KEY=phc_...
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
Shipr is configured to reverse-proxy PostHog requests through Next.js rewrites (see next.config.ts), which helps bypass ad blockers.

Configure Sentry (Optional)

Sentry provides error tracking and performance monitoring.
1

Create a Sentry project

  1. Go to sentry.io
  2. Create an account and organization
  3. Create a new Next.js project
2

Add Sentry credentials

# Auth token for uploading source maps
SENTRY_AUTH_TOKEN=sntrys_...

# Your Sentry DSN
NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/...
3

Source maps

Source maps are automatically uploaded during pnpm build via the @sentry/nextjs plugin.
Source maps help you debug production errors with readable stack traces.

Configure File Upload Rate Limiting (Optional)

Control image upload limits per user:
# Max uploads per user in the time window
FILE_IMAGE_UPLOAD_RATE_LIMIT_MAX_UPLOADS=10

# Time window in milliseconds (60000 = 1 minute)
FILE_IMAGE_UPLOAD_RATE_LIMIT_WINDOW_MS=60000
Set either value to 0 to disable rate limiting for image uploads.

Complete .env Example

Here’s what your .env should look like with all required services configured:
# Site
NEXT_PUBLIC_SITE_URL=http://localhost:3000

# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
CLERK_JWT_ISSUER_DOMAIN=https://...clerk.accounts.dev
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

# Convex Database
NEXT_PUBLIC_CONVEX_URL=https://...convex.cloud

# Resend Email
RESEND_API_KEY=re_...
RESEND_FROM_EMAIL=[email protected]

# Vercel AI Gateway (optional)
AI_GATEWAY_API_KEY=vck_...

# PostHog Analytics (optional)
NEXT_PUBLIC_POSTHOG_KEY=phc_...
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

# Sentry Error Tracking (optional)
SENTRY_AUTH_TOKEN=sntrys_...
NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/...

Start Development

With all services configured, you’re ready to run Shipr:
1

Start Convex

In one terminal:
npx convex dev
2

Start Next.js

In another terminal:
pnpm dev
3

Open your browser

Verify Setup

1

Check authentication

  1. Click “Sign Up” in the header
  2. Create a test account
  3. Complete the onboarding flow
  4. Verify you can access the dashboard
2

Check Convex sync

  1. Open the Convex dashboard
  2. Navigate to your project’s data
  3. Check the users table - you should see your test user
3

Check email (if configured)

Test the email endpoint:
# In the dashboard, navigate to a page that triggers a welcome email
# Or test via the API route directly
4

Check AI chat (if configured)

  1. Navigate to /dashboard/chat
  2. Send a test message
  3. Verify you get a response from the AI

Database Schema

Shipr’s Convex schema (convex/schema.ts) includes:

Users Table

FieldTypeDescription
clerkIdstringClerk user ID (indexed)
emailstringPrimary email address
namestring?Full name
imageUrlstring?Profile image URL
planstring?Billing plan: "free" or "pro"
onboardingCompletedboolean?Whether user finished onboarding
onboardingStepstring?Current step: "welcome", "profile", etc.

Files Table

FieldTypeDescription
storageIdid("_storage")Convex storage reference
userIdid("users")Owning user
fileNamestringOriginal filename (sanitized)
mimeTypestringMIME type (e.g., "image/png")
sizenumberFile size in bytes

Chat Tables

chatThreads:
  • userId - Owner of the thread
  • title - Auto-generated thread title
  • lastMessageAt - Timestamp for sorting
chatMessages:
  • userId - Message owner
  • threadId - Parent thread
  • role - "user" or "assistant"
  • content - Message text
All tables automatically include _id and _creationTime fields from Convex.

Next Steps

Architecture

Learn how Shipr’s components work together

Authentication

Deep dive into Clerk and user sync

AI Chat

Configure and extend the AI chat feature

Deployment

Deploy to production on Vercel

Troubleshooting

Module not found errors

# Clear node_modules and reinstall
rm -rf node_modules
pnpm install

Convex schema errors

# Push schema again
npx convex dev --once

Environment variables not loading

  1. Verify .env file exists in the root directory
  2. Restart both npx convex dev and pnpm dev
  3. Check for typos in variable names (they’re case-sensitive)

Clerk/Convex authentication mismatch

  1. Verify CLERK_JWT_ISSUER_DOMAIN matches in:
    • Your .env file
    • Convex dashboard authentication settings
  2. Ensure it includes https:// protocol
  3. Restart all servers after changing

Port conflicts

# Use a different port
pnpm dev -- -p 3001

# Update your site URL
NEXT_PUBLIC_SITE_URL=http://localhost:3001

Build docs developers (and LLMs) love