Splits the two hostnames across one deployment. No files move: the Next app still serves every route on both hosts, and the middleware decides per host which paths it owns and 301s the rest. /login and /signup stay on www - all 82 marketing CTAs point at /signup, which carries a hard canonical to www plus ad traffic. src/lib/hosts.ts is the single source of truth for the boundary (APP_PATH_PREFIXES, isAppPath, wwwUrl, appUrl, urlForPath). The middleware and every absolute-URL builder read from it so they cannot drift apart. - Split the overloaded NEXT_PUBLIC_APP_URL into a www and an app origin. It previously fed both public URLs and in-app URLs, so any single value was wrong somewhere. Most important: QRCodeCard encodes this origin into the QR code the user downloads and prints, so it must stay on www. - Route Stripe return URLs, email links and OAuth redirects per path rather than against one origin, so /dashboard lands on app and /pricing on www. - Cross the host boundary once, after a successful login: the router cannot push across origins, so that jump needs a full load. The user arrives signed in because the session cookie is scoped to COOKIE_DOMAIN. - Keep the app host out of search indexes: X-Robots-Tag on every response plus a Disallow-all robots.txt via rewrite, and /sitemap.xml redirects to www. - Point the TikTok callback fallback at www explicitly. It used to read NEXT_PUBLIC_APP_URL, whose meaning changed here, and only the apex domain is verified with TikTok. Host splitting is inert while both origins are equal, so development is unaffected. Verified: tsc clean, production build succeeds including the Edge middleware bundle, and the path-to-host mapping is unit-checked (prefix traps like /created and /settings-guide stay on www, query strings do not break matching). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
76 lines
2.6 KiB
Plaintext
76 lines
2.6 KiB
Plaintext
# Environment Configuration
|
|
NODE_ENV=development
|
|
PORT=3000
|
|
|
|
# Database Configuration (PostgreSQL)
|
|
POSTGRES_USER=postgres
|
|
POSTGRES_PASSWORD=postgres
|
|
POSTGRES_DB=qrmaster
|
|
|
|
# For local development (without Docker):
|
|
# DATABASE_URL=postgresql://postgres:postgres@localhost:5435/qrmaster?schema=public
|
|
# For Docker Compose (internal Docker network):
|
|
DATABASE_URL=postgresql://postgres:postgres@db:5432/qrmaster?schema=public
|
|
|
|
# NextAuth Configuration
|
|
NEXTAUTH_URL=http://localhost:3050
|
|
NEXTAUTH_SECRET=your-secret-key-here-change-in-production
|
|
|
|
# Session cookie scope. Leave EMPTY for local development (browsers reject dotted
|
|
# domains on localhost). In production set to `.qrmaster.net` so the session is shared
|
|
# between www.qrmaster.net and app.qrmaster.net. Only honoured when NODE_ENV=production.
|
|
COOKIE_DOMAIN=
|
|
|
|
# Host split: marketing/SEO on WWW, the logged-in app on APP. Keep both pointing at the
|
|
# same origin locally so nothing redirects across hosts in development.
|
|
# In production: NEXT_PUBLIC_WWW_URL=https://www.qrmaster.net
|
|
# NEXT_PUBLIC_APP_URL=https://app.qrmaster.net
|
|
# NEXT_PUBLIC_WWW_URL must stay on www - it is the origin encoded into downloaded QR
|
|
# codes and used for public links in emails.
|
|
NEXT_PUBLIC_WWW_URL=http://localhost:3050
|
|
NEXT_PUBLIC_APP_URL=http://localhost:3050
|
|
|
|
# OAuth Providers (Optional)
|
|
GOOGLE_CLIENT_ID=
|
|
GOOGLE_CLIENT_SECRET=
|
|
|
|
# Redis Configuration (Optional - for rate limiting and caching)
|
|
REDIS_URL=redis://redis:6379
|
|
|
|
# Security
|
|
# Used for hashing IP addresses in analytics
|
|
IP_SALT=your-ip-salt-here-change-in-production
|
|
|
|
# Features
|
|
ENABLE_DEMO=false
|
|
|
|
# SEO Configuration
|
|
# Set to 'true' in production to allow search engine indexing
|
|
NEXT_PUBLIC_INDEXABLE=true
|
|
|
|
# Stripe Payment Configuration (Optional - for subscription payments)
|
|
# Get your keys from: https://dashboard.stripe.com/apikeys
|
|
STRIPE_SECRET_KEY=
|
|
STRIPE_WEBHOOK_SECRET=
|
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
|
|
|
|
# Stripe Price IDs (create these in your Stripe dashboard)
|
|
# NEXT_PUBLIC_STRIPE_FREE_PRICE_ID=price_xxx
|
|
# NEXT_PUBLIC_STRIPE_PRO_PRICE_ID=price_xxx
|
|
# NEXT_PUBLIC_STRIPE_BUSINESS_PRICE_ID=price_xxx
|
|
|
|
# Analytics (Optional - PostHog)
|
|
NEXT_PUBLIC_POSTHOG_KEY=
|
|
NEXT_PUBLIC_POSTHOG_HOST=https://app.posthog.com
|
|
|
|
# Analytics (Optional - Microsoft Clarity session recordings & heatmaps)
|
|
NEXT_PUBLIC_CLARITY_PROJECT_ID=
|
|
|
|
# TikTok Content Posting API (Hermes Agent automated posting)
|
|
TIKTOK_CLIENT_KEY=
|
|
TIKTOK_CLIENT_SECRET=
|
|
TIKTOK_REDIRECT_URI=https://qrmaster.net/api/tiktok/callback
|
|
# Optional: protects /api/tiktok/connect from being triggered by strangers
|
|
TIKTOK_ADMIN_KEY=
|
|
TIKTOK_EXPECTED_OPEN_ID=
|