← Back to list

vercel-deploy
by aiskillstore
Security-audited skills for Claude, Codex & Claude Code. One-click install, quality verified.
⭐ 102🍴 3📅 Jan 23, 2026
SKILL.md
name: vercel-deploy description: | Use when deploying Next.js applications to Vercel. Triggers for: vercel.json configuration, build optimization, environment variable setup, custom domain configuration, API proxy setup, or deployment troubleshooting. NOT for: backend-only deployments, non-Vercel hosting, or local development setup.
Vercel Deployment Skill
Expert deployment of Next.js applications to Vercel with optimal build settings, environment configuration, and custom domain setup.
Quick Reference
| Task | File/Command |
|---|---|
| Configure build | vercel.json |
| Set env vars | Vercel Dashboard or CLI |
| Deploy | vercel --prod |
| Check status | vercel inspect |
| Custom domain | Vercel Dashboard > Settings > Domains |
Project Structure
project/
├── vercel.json # Vercel configuration
├── next.config.js # Next.js configuration
├── .env.local # Local development (not committed)
├── .env.example # Template (committed)
├── docs/
│ └── deployment.md # Deployment documentation
└── frontend/ # Next.js app
├── app/
├── public/
└── src/
vercel.json Configuration
Basic Configuration
{
"buildCommand": "npm run build",
"outputDirectory": ".next",
"installCommand": "npm install",
"framework": "nextjs",
"regions": ["iad1"],
"env": {
"NEXT_PUBLIC_API_URL": "@api_url"
}
}
Advanced Configuration with Rewrites
{
"version": 2,
"buildCommand": "npm run build",
"outputDirectory": ".next",
"installCommand": "npm install",
"framework": "nextjs",
"regions": ["iad1"],
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://api.yourdomain.com/:path*"
}
],
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
]
},
{
"source": "/static/:path*",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
},
{
"source": "/api/:path*",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
}
]
}
],
"redirects": [
{
"source": "/old-path/:path*",
"destination": "/new-path/:path*",
"permanent": true
},
{
"source": "/www/:path*",
"destination": "/:path*",
"permanent": true
}
]
}
Next.js Config Integration
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// Output configuration for Vercel
output: 'standalone',
// Image optimization
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'api.yourdomain.com',
pathname: '/uploads/**',
},
],
formats: ['image/avif', 'image/webp'],
},
// Headers for security
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'X-DNS-Prefetch-Control',
value: 'on',
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin',
},
],
},
];
},
// Redirects
async redirects() {
return [
{
source: '/legacy/:path*',
destination: '/:path*',
permanent: true,
},
];
},
// Experimental features
experimental: {
serverActions: {
allowedOrigins: ['yourdomain.com'],
},
},
};
module.exports = nextConfig;
Environment Variables
Variable Naming Convention
| Prefix | Access | Description |
|---|---|---|
NEXT_PUBLIC_ | Client + Server | Exposed to browser |
| No prefix | Server only | Backend/API use only |
Required Variables
# .env.example - Copy to .env.local for local dev
# API Configuration
# Backend API URL (development)
NEXT_PUBLIC_API_URL="http://localhost:8000/api/v1"
# Authentication
NEXT_PUBLIC_AUTH_ENABLED="true"
# Feature Flags
NEXT_PUBLIC_ENABLE_DARK_MODE="true"
NEXT_PUBLIC_SHOW_BETA_FEATURES="false"
Production Variables (Set in Vercel Dashboard)
# Environment variables for Production
# API Configuration
NEXT_PUBLIC_API_URL="https://api.yourdomain.com"
# Optional: Analytics
NEXT_PUBLIC_GA_ID="G-XXXXXXXXXX"
NEXT_PUBLIC_POSTHOG_KEY="phc_xxx"
# Optional: Error tracking
NEXT_PUBLIC_SENTRY_DSN="https://xxx@sentry.io/xxx"
Sensitive Variables (Server-Only)
These should NOT have NEXT_PUBLIC_ prefix:
# Server-only (never exposed to client)
API_SECRET_KEY="vercel-secret-key"
DATABASE_URL="postgresql://..."
REDIS_URL="redis://..."
Vercel CLI Deployment
Installation and Login
# Install Vercel CLI
npm i -g vercel
# Login to Vercel
vercel login
# Link to project
cd frontend
vercel link
Deployment Commands
# Deploy to preview (staging)
vercel
# Deploy to production
vercel --prod
# Deploy with environment
vercel --env=NODE_ENV=production
# Pull environment variables from Vercel
vercel env pull .env.local
CI/CD Deployment
# In CI pipeline
npm i -g vercel
vercel --token=$VERCEL_TOKEN --yes
Custom Domain Setup
Adding Domain in Vercel
- Go to Vercel Dashboard > Project > Settings > Domains
- Add your domain (e.g.,
yourdomain.com) - Configure DNS records
DNS Configuration
# For root domain (yourdomain.com)
Type: A
Name: @
Value: 76.76.21.21
# For www subdomain
Type: CNAME
Name: www
Value: cname.vercel-dns.com.
# For API subdomain (optional)
Type: CNAME
Name: api
Value: cname.vercel-dns.com.
www to Root Redirect
{
"redirects": [
{
"source": "/:path*",
"destination": "https://yourdomain.com/:path*",
"permanent": true
}
]
}
API Proxy Setup
Option 1: Vercel Rewrites (Recommended)
{
"rewrites": [
{
"source": "/api/:path*",
"destination": "https://api.yourdomain.com/:path*"
}
]
}
Option 2: Next.js Rewrite
// next.config.js
async rewrites() {
return [
{
source: '/api/:path*',
destination: `${process.env.NEXT_PUBLIC_API_URL}/:path*`,
},
];
}
Edge Function for API (Advanced)
// frontend/app/api/[...route]/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/v1/endpoint`,
{
headers: {
'Authorization': request.headers.get('Authorization') || '',
'Content-Type': 'application/json',
},
}
);
const data = await response.json();
return NextResponse.json(data);
}
Build Optimization
Build Command
# Standard build
npm run build
# With TypeScript check only
npm run build -- --no-lint
# Custom build
next build
Performance Settings
// next.config.js
const nextConfig = {
// Enable SWC minifier (faster builds)
swcMinify: true,
// Compiler options
compiler: {
removeConsole: process.env.NODE_ENV === 'production',
},
// Image optimization
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
// Enable react strict mode
reactStrictMode: true,
// Generate Etag
generateEtags: true,
};
Bundle Analysis
# Install bundle analyzer
npm install -D @next/bundle-analyzer
# next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
// your config
});
Error Pages
Custom 404 Page
// frontend/app/not-found.tsx
import Link from 'next/link';
export default function NotFound() {
return (
<div className="min-h-screen flex flex-col items-center justify-center">
<h1 className="text-4xl font-bold">404 - Page Not Found</h1>
<p className="mt-2 text-gray-600">
The page you're looking for doesn't exist.
</p>
<Link
href="/"
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
>
Go Home
</Link>
</div>
);
}
Custom 500 Page
// frontend/app/error.tsx
'use client';
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div className="min-h-screen flex flex-col items-center justify-center">
<h1 className="text-4xl font-bold">Something went wrong!</h1>
<p className="mt-2 text-gray-600">
An unexpected error occurred.
</p>
<button
onClick={() => reset()}
className="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
>
Try Again
</button>
</div>
);
}
Global Error Boundary
// frontend/app/global-error.tsx
'use client';
export default function GlobalError({
error,
}: {
error: Error & { digest?: string };
}) {
return (
<html>
<body>
<div className="min-h-screen flex items-center justify-center">
<h1 className="text-2xl">Application Error</h1>
</div>
</body>
</html>
);
}
Deployment Checklist
- Build succeeds locally:
npm run buildcompletes without errors - Build succeeds on Vercel: Deploy preview builds correctly
- Correct API URLs: NEXT_PUBLIC_API_URL points to correct environment
- No sensitive vars exposed: No
NEXT_PUBLIC_prefix on secrets - 404 page configured: Custom not-found.tsx exists
- 500 page configured: Custom error.tsx exists
- Custom domain set up: DNS records configured correctly
- HTTPS enforced: Automatic SSL certificate
- Redirects configured: www to root or vice versa
- Cache headers set: Static assets properly cached
Deployment Documentation Template
# Deployment Guide
## Quick Deploy
[](https://vercel.com/new)
## Environment Variables
### Development
```bash
NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1
Production
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
Custom Domain
- Add
yourdomain.comin Vercel Dashboard > Settings > Domains - Configure DNS:
- A record:
@->76.76.21.21 - CNAME:
www->cname.vercel-dns.com
- A record:
Troubleshooting
Build Fails
# Run locally to see error
npm run build
Environment Variables Not Working
- Check variable name starts with
NEXT_PUBLIC_for client access - Redeploy after adding new variables
404 on Production
- Verify
vercel.jsonoutputDirectory matches build output - Check page files are in
app/directory (App Router)
## Integration Points
| Skill | Integration |
|-------|-------------|
| `@frontend-nextjs-app-router` | Next.js App Router configuration |
| `@env-config` | Environment variable management |
| `@tailwind-css` | CSS build optimization |
| `@api-route-design` | API routes and rewrites |
| `@error-handling` | Custom error pages |
Score
Total Score
60/100
Based on repository quality metrics
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
✓人気
GitHub Stars 100以上
+5
✓最近の活動
1ヶ月以内に更新
+10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
✓タグ
1つ以上のタグが設定されている
+5
Reviews
💬
Reviews coming soon
