From webapp-toolkit
Use when setting up Vercel projects, configuring blob storage, managing environment variables, or setting up custom domains with wildcard subdomains. Critical for avoiding env var loss and understanding wildcard routing requirements.
How this skill is triggered — by the user, by Claude, or both
Slash command
/webapp-toolkit:vercel-infrastructureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide for setting up Vercel infrastructure including blob storage, environment variables, custom domains, and wildcard subdomain routing. Contains critical warnings about common pitfalls that can cause data loss.
Guide for setting up Vercel infrastructure including blob storage, environment variables, custom domains, and wildcard subdomain routing. Contains critical warnings about common pitfalls that can cause data loss.
vercel env pull OVERWRITES .env.localThis is the most dangerous pitfall. Running vercel env pull completely replaces your local .env.local file. Any variables not stored in Vercel will be LOST.
# DANGER: This will DELETE any local-only variables
vercel env pull .env.local --yes
What gets lost:
DATABASE_URL if you added it locallyAUTH_SECRET if generated locallyNEVER add variables only to .env.local. Always:
echo "value" | vercel env add VAR_NAME productionvercel env pull .env.local --yesThis ensures vercel env pull never loses variables.
If you accidentally overwrote .env.local:
# Recover DATABASE_URL from Neon
neonctl set-context --org-id <org-id>
neonctl projects list
neonctl connection-string --project-id <project-id>
# Generate new AUTH_SECRET
openssl rand -base64 32
# Add recovered values to Vercel, then pull
echo "<value>" | vercel env add DATABASE_URL production
vercel env pull .env.local --yes
Vercel env pull sometimes adds \n at end of values:
sed -i '' 's/\\n"$/"/g' .env.local
vercel link --yes
This creates .vercel/project.json with project and org IDs.
Prevent deployment errors from special files:
.beads/
.neon/
Socket files (like .beads/bd.sock) cause "Unknown system error -102" during deployment.
vercel blob store add <store-name>
This automatically:
BLOB_READ_WRITE_TOKEN to your Vercel projectvercel env pull .env.local --yes
import { put, del } from "@vercel/blob";
// Upload file
const blob = await put(`${userId}/${versionId}/index.html`, content, {
access: "public",
addRandomSuffix: false,
});
// Delete file
await del(blob.url);
echo "value" | vercel env add VAR_NAME production
echo "value" | vercel env add VAR_NAME preview
echo "value" | vercel env add VAR_NAME development
vercel env ls
vercel env rm VAR_NAME production -y
| Variable | Source | Notes |
|---|---|---|
DATABASE_URL | Neon CLI or dashboard | neonctl connection-string --project-id <id> |
AUTH_SECRET | Generate | openssl rand -base64 32 |
BLOB_READ_WRITE_TOKEN | Auto-added | Created with blob store |
NEXT_PUBLIC_* | Manual | Client-visible vars need this prefix |
Vercel's .vercel.app domain does NOT support wildcard subdomains.
project.vercel.app workssubdomain.project.vercel.app does NOT workFor wildcard subdomain routing, you MUST use a custom domain.
# Add root domain
vercel domains add yourdomain.com
# Add wildcard domain
vercel domains add "*.yourdomain.com"
This is the most common wildcard setup failure.
For wildcard domains (*.yourdomain.com), CNAME records are NOT sufficient. You MUST delegate your domain to Vercel's nameservers.
Root domain only (no wildcards):
| Type | Host | Value |
|---|---|---|
| A | @ | 216.198.79.1 |
Wildcard domains - Change nameservers at your registrar to:
| Nameserver |
|---|
ns1.vercel-dns.com |
ns2.vercel-dns.com |
Why nameservers are required for wildcards:
Option 1: Nameservers (Required for wildcards)
ns1.vercel-dns.com and ns2.vercel-dns.comOption 2: A/CNAME Records (Root domain only, no wildcards)
| Type | Host | Value |
|---|---|---|
| A | @ | 216.198.79.1 |
| CNAME | www | cname.vercel-dns.com |
Note: Vercel's IP addresses are being updated. Old values (76.76.21.21, cname.vercel-dns.com) still work but new IPs are recommended.
Vercel creates SSL certificates asynchronously. After adding domains:
Check status:
curl -v https://test.yourdomain.com/ 2>&1 | grep -i ssl
Check the Vercel dashboard for domain status:
After changing nameservers:
dig NS yourdomain.comStore domain in environment variable for flexibility:
// lib/routing.ts
export const APP_DOMAIN = process.env.NEXT_PUBLIC_APP_DOMAIN || "localhost";
export function extractSubdomain(hostname: string): string | null {
const host = hostname.split(":")[0];
// Local development
if (host === "localhost" || host.endsWith(".localhost")) {
const parts = host.split(".");
if (parts.length === 2 && parts[1] === "localhost") {
return parts[0];
}
return null;
}
// Production - works with any domain length
const domainParts = APP_DOMAIN.split(".");
if (host === APP_DOMAIN) return null;
if (host.endsWith("." + APP_DOMAIN)) {
const hostParts = host.split(".");
const subdomainParts = hostParts.length - domainParts.length;
if (subdomainParts === 1) {
const subdomain = hostParts[0];
return subdomain === "www" ? null : subdomain;
}
if (subdomainParts === 2 && hostParts[0] === "www") {
return hostParts[1];
}
}
return null;
}
This works with both 2-part (canvas.site) and 3-part (project.vercel.app) domains without code changes.
When switching domains, only change the env var:
vercel env rm NEXT_PUBLIC_APP_DOMAIN production -y
echo "newdomain.com" | vercel env add NEXT_PUBLIC_APP_DOMAIN production
vercel deploy --prod
vercel deploy --prod
| Error | Cause | Fix |
|---|---|---|
Unknown system error -102 | Socket file in upload | Add to .vercelignore |
ENOENT on env var | Variable not set | Add via vercel env add |
| Build fails | Missing env var at build | Ensure var exists for all environments |
vercel link # Link to project
vercel env ls # List env vars
vercel env add NAME ENV # Add var (pipe value via stdin)
vercel env rm NAME ENV -y # Remove var
vercel env pull .env.local # Pull to local (OVERWRITES!)
vercel deploy --prod # Deploy to production
vercel domains add DOMAIN # Add domain
vercel domains ls # List domains
vercel blob store add NAME # Create blob store
neonctl set-context --org-id ID # Set org context
neonctl projects list # List projects
neonctl connection-string --project-id ID # Get DATABASE_URL
neonctl branches list --project-id ID # List branches
vercel link --yes.vercelignore with .beads/, .neon/vercel env pull .env.local --yessed -i '' 's/\\n"$/"/g' .env.localvercel blob store add <name> (if needed)vercel deploy --prodvercel domains add yourdomain.comvercel domains add "*.yourdomain.com"ns1.vercel-dns.com and ns2.vercel-dns.comcurl https://test.yourdomain.com/npx claudepluginhub zainrizvi/webapp-toolkit --plugin webapp-toolkitGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.