vercel-deployment
Next.jsアプリケーションをVercelにデプロイするための専門的な知識を提供するスキルです。デプロイ設定やトラブルシューティングなど、Vercelへの公開に関する幅広いサポートに対応します。
description の原文を見る
Expert knowledge for deploying to Vercel with Next.js
SKILL.md 本文
Vercel デプロイメント
Vercelへの Next.js デプロイに関するエキスパートナレッジ
機能
- vercel
- deployment
- edge-functions
- serverless
- environment-variables
前提条件
- 必須スキル: nextjs-app-router
パターン
環境変数セットアップ
すべての環境に対して環境変数を適切に設定します
使用する場面: Vercelで新しいプロジェクトを設定する時
// Vercel内の3つの環境:
// - Development (ローカル)
// - Preview (PR デプロイ)
// - Production (メインブランチ)
// Vercel ダッシュボード内:
// Settings → Environment Variables
// PUBLIC変数 (ブラウザに露出)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
// PRIVATE変数 (サーバーのみ)
SUPABASE_SERVICE_ROLE_KEY=eyJ... // NEXT_PUBLIC_を使用しないこと!
DATABASE_URL=postgresql://...
// 環境ごとの値:
// Production: 実データベース、本番API キー
// Preview: ステージングデータベース、テストAPI キー
// Development: ローカル/開発値 (.env.localにも記載)
// コード内で環境を確認:
const isProduction = process.env.VERCEL_ENV === 'production'
const isPreview = process.env.VERCEL_ENV === 'preview'
Edge vs Serverless Functions
API ルートに適切なランタイムを選択します
使用する場面: APIルートまたはミドルウェアを作成する時
// EDGE RUNTIME - 高速なコールドスタート、限定的なAPI
// 向いている用途: 認証チェック、リダイレクト、シンプルな変換
// app/api/hello/route.ts
export const runtime = 'edge'
export async function GET() {
return Response.json({ message: 'Hello from Edge!' })
}
// middleware.ts (常にedge)
export function middleware(request: NextRequest) {
// ここで高速な認証チェック
}
// SERVERLESS (Node.js) - 完全なNode API、遅いコールドスタート
// 向いている用途: データベースクエリ、ファイル操作、重い計算
// app/api/users/route.ts
export const runtime = 'nodejs' // デフォルト、省略可能
export async function GET() {
const users = await db.query('SELECT * FROM users')
return Response.json(users)
}
ビルド最適化
デプロイを高速化し、バンドルサイズを小さくするために最適化します
使用する場面: 本番デプロイに向けて準備する時
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// 出力を最小化
output: 'standalone', // Docker/セルフホスティング用
// 画像の最適化
images: {
remotePatterns: [
{ hostname: 'your-cdn.com' },
],
},
// バンドル分析 (開発のみ)
// npm install @next/bundle-analyzer
...(process.env.ANALYZE === 'true' && {
webpack: (config) => {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
config.plugins.push(new BundleAnalyzerPlugin())
return config
},
}),
}
// サーバーレス関数のサイズを削減:
// - 重いライブラリに動的インポートを使用
// - バンドルをチェック: npx @next/bundle-analyzer
プレビューデプロイメントワークフロー
PR レビュー用のプレビューデプロイメントを使用します
使用する場面: チーム開発ワークフローを設定する時
// すべてのPRは自動的にユニークなプレビューURLを取得
// プレビューデプロイメントをパスワードで保護:
// Vercel ダッシュボード → Settings → Deployment Protection
// プレビュー用に異なる環境変数を使用:
// - PREVIEW: ステージングデータベースを使用
// - PRODUCTION: 本番データベースを使用
// コード内でプレビューを検出:
if (process.env.VERCEL_ENV === 'preview') {
// 「Preview」バナーを表示
// テスト決済処理を使用
// アナリティクスを無効化
}
// PR にプレビューURLをコメント (Vercel GitHub統合で自動)
カスタムドメイン設定
適切なSSLを使用してカスタムドメインを設定します
使用する場面: 本番環境に移行する時
// Vercel ダッシュボード → Domains
// ドメインを追加:
// - example.com (apex/ルート)
// - www.example.com (サブドメイン)
// DNS設定 (ドメインレジストラで):
// Type: A, Name: @, Value: 76.76.21.21
// Type: CNAME, Name: www, Value: cname.vercel-dns.com
// wwwをapexにリダイレクト (またはその逆):
// Vercelが自動的に処理
// next.config.js でのリダイレクト:
module.exports = {
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true, // 308
},
]
},
}
危険な落とし穴
NEXT_PUBLIC_ で機密情報を公開
重大度: 重大
状況: 機密API キーにNEXT_PUBLIC_プレフィックスを使用している
症状:
- ブラウザDevTools → Sourcesに機密情報が見える
- セキュリティ監査で公開キーが検出される
- 不明なソースからの予期しないAPI アクセス
なぜこれが問題か: NEXT_PUBLIC_プレフィックスが付いた変数はビルド時にJavaScript バンドルに埋め込まれます。誰でもブラウザDevToolsで確認できます。 これは全ユーザーと潜在的な攻撃者も含まれます。
推奨される対処:
NEXT_PUBLIC_は本当に公開する値のみに使用:
// NEXT_PUBLIC_の使用は安全
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... // Anonキーは公開を想定
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
NEXT_PUBLIC_GA_ID=G-XXXXXXX
// NEXT_PUBLIC_を使用してはいけない
SUPABASE_SERVICE_ROLE_KEY=eyJ... // データベースへの完全アクセス!
STRIPE_SECRET_KEY=sk_live_... // カードを請求できる!
DATABASE_URL=postgresql://... // 直接DBアクセス!
JWT_SECRET=... // トークンを偽造できる!
// サーバーのみの変数にアクセス:
// - Server Components (app router)
// - API Routes
// - Server Actions ('use server')
// - getServerSideProps (pages router)
プレビューデプロイメントが本番データベースを使用
重大度: 高
状況: プレビュー用に個別の環境変数を設定していない
症状:
- テストデータが本番に表示される
- PR マージ後に本番データが破損
- ユーザーがテストアカウント/コンテンツを見ている
なぜこれが問題か: プレビューデプロイメントは未テストコードを実行します。本番 データベースを使用していると、PR内のバグが本番データを破損する 可能性があります。また、テスターがテストデータを作成すると、 本番に表示されることがあります。
推奨される対処:
各環境に別々のデータベースを設定:
// Vercel ダッシュボード → Settings → Environment Variables
// Production (productionエンバイロンメントのみ):
DATABASE_URL=postgresql://prod-host/prod-db
// Preview (previewエンバイロンメントのみ):
DATABASE_URL=postgresql://staging-host/staging-db
// またはVercelのブランチングデータベース機能を使用:
// - Neon、PlanetScale、Supabaseはすべてブランチデータベースに対応
// - 各PR に対して自動的にプレビューDBを作成
// Supabaseの場合、ステージングプロジェクトを作成:
// Production:
NEXT_PUBLIC_SUPABASE_URL=https://prod-xxx.supabase.co
// Preview:
NEXT_PUBLIC_SUPABASE_URL=https://staging-xxx.supabase.co
サーバーレス関数が大きすぎてコールドスタートが遅い
重大度: 高
状況: APIルートまたはサーバーコンポーネントの初期読み込みが遅い
症状:
- 最初のリクエストに3~10秒以上かかる
- その後のリクエストは高速
- 関数サイズ制限超過エラー
- デプロイがサイズエラーで失敗
なぜこれが問題か: Vercel サーバーレス関数には50MB (圧縮) の制限があります。 大きな関数はコールドスタートが遅くなります (1~5秒以上)。 puppeteerやsharpなどの重い依存関係がこれを引き起こします。
推奨される対処:
関数サイズを削減:
// 1. 重いライブラリに動的インポートを使用
export async function GET() {
const sharp = await import('sharp') // 必要な時のみ読み込み
// ...
}
// 2. 重い処理をedgeまたは外部サービスに移行
export const runtime = 'edge' // はるかに小さく、コールドスタートが高速
// 3. バンドルサイズをチェック
// npx @next/bundle-analyzer
// 大きな依存関係を探す
// 4. 重いタスクに外部サービスを使用
// - 画像処理: Cloudinary、imgix
// - PDF生成: API サービス
// - Puppeteer: Browserless.io
// 5. 複数の関数に分割
// /api/heavy-task/start - ジョブをキューに入れる
// /api/heavy-task/status - 進捗を確認
Edge ランタイムでNode.js API が見つからない
重大度: 高
状況: Edge ランタイム関数でNode.js API を使用している
症状:
- X is not defined (実行時)
- Cannot find module fs
- ローカルでは動くが、デプロイ後は失敗
- ミドルウェアがクラッシュ
なぜこれが問題か: Edge ランタイムはNode.js ではなくV8で実行されます。多くの Node API が不足しています: fs、path、crypto (部分的)、 child_process、ほとんどのネイティブモジュール。コードは実行時に 「X is not defined」で失敗します。
推奨される対処:
Edge を使用する前にAPI互換性を確認:
// Edge でサポート:
// - fetch、Request、Response
// - crypto.subtle (Web Crypto)
// - TextEncoder、TextDecoder
// - URL、URLSearchParams
// - Headers、FormData
// - setTimeout、setInterval
// Edge でサポートされない:
// - fs、path、os
// - Buffer (Uint8Arrayを使用)
// - crypto.createHash (crypto.subtle を使用)
// - ネイティブdepを持つほとんどのnpmパッケージ
// Node.js API が必要な場合:
export const runtime = 'nodejs' // 代わりにNode ランタイムを使用
// Edge でのcryptoハッシング:
// 間違い
import { createHash } from 'crypto' // Edge で失敗
// 正しい
async function hash(message: string) {
const encoder = new TextEncoder()
const data = encoder.encode(message)
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
return Array.from(new Uint8Array(hashBuffer))
.map(b => b.toString(16).padStart(2, '0'))
.join('')
}
関数タイムアウトで不完全な操作
重大度: 中
状況: 長時間実行される操作がタイムアウトしている
症状:
- Task timed out after X seconds
- 不完全なデータベース操作
- 部分的なファイルアップロード
- 実行中に関数が強制終了
なぜこれが問題か: Vercel にはタイムアウト制限があります:
- Hobby: 10秒
- Pro: 60秒 (300秒に増加可能)
- Enterprise: 900秒
この制限を超える操作は実行中に強制終了されます。
推奨される対処:
長い操作を適切に処理:
// 1. 早期にリターンして非同期で処理
export async function POST(request: Request) {
const data = await request.json()
// バックグラウンド処理用にキューに追加
await queue.add('process-data', data)
// 即座にリターン
return Response.json({ status: 'queued' })
}
// 2. 長いレスポンスにストリーミングを使用
export async function GET() {
const stream = new ReadableStream({
async start(controller) {
for (const chunk of generateChunks()) {
controller.enqueue(chunk)
await sleep(100) // タイムアウトを防止
}
controller.close()
}
})
return new Response(stream)
}
// 3. 重い処理に外部サービスを使用
// - サーバーレス関数をトリガーしてジョブIDを返す
// - バックグラウンドで処理 (Inngest、Trigger.dev)
// - クライアントが完了をポーリング
// 4. タイムアウトを増加させる (Pro プラン)
// vercel.json:
{
"functions": {
"app/api/slow/route.ts": {
"maxDuration": 60
}
}
}
ビルド時には存在するが実行時には環境変数が見つからない
重大度: 中
状況: 環境変数がビルドでは機能するが実行時に見つからない
症状:
- 本番環境で環境変数が未定義
- ダッシュボードで更新後も値が変わらない
- 開発では動くが、本番で値が異なる
- 新しいデプロイが必要になる
なぜこれが問題か: 一部の環境変数はビルド時のみ利用可能です (バンドルにハードコード)。 ビルド時の値を期待しているが、実行時値が得られていない場合、 ビルド時の値または未定義になります。
推奨される対処:
環境変数がいつ読まれるかを理解:
// ビルド時 (バンドルにハードコード):
// - NEXT_PUBLIC_* 変数
// - next.config.js
// - generateStaticParams
// - 静的ページ
// 実行時 (リクエストごとに読み込み):
// - Server Components (キャッシュなし)
// - API Routes
// - Server Actions
// - ミドルウェア
// 実行時読み込みを強制:
export const dynamic = 'force-dynamic'
// ランタイムである必要がある設定:
// NEXT_PUBLIC_ を使用しないで、サーバーで読み込んでクライアントに渡す
// 必要な環境変数を確認:
// ビルド: URL、公開キー、機能フラグ (静的の場合)
// ランタイム: 機密情報、データベースURL、ユーザー固有の設定
異なるドメインからのAPIルート呼び出しで CORS エラー
重大度: 中
状況: 別ドメイン上のフロントエンドがAPIルートを呼び出せない
症状:
- ブラウザコンソールにCORS ポリシーエラー
- Access-Control-Allow-Origin ヘッダーがない
- Postman では動くがブラウザでは失敗
- 同一オリジンでは動くが、クロスオリジンでは失敗
なぜこれが問題か: デフォルトでは、ブラウザはクロスオリジンリクエストをブロックします。 Vercel は自動的にCORS ヘッダーを追加しません。フロントエンドが 別のドメイン (または開発時のlocalhost) にある場合、リクエストは 失敗します。
推奨される対処:
APIルートにCORS ヘッダーを追加:
// app/api/data/route.ts
export async function GET(request: Request) {
const data = await fetchData()
return Response.json(data, {
headers: {
'Access-Control-Allow-Origin': '*', // または特定のドメイン
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
})
}
// プリフライトリクエストを処理
export async function OPTIONS() {
return new Response(null, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
})
}
// またはnext.config.js で全ルートに設定:
module.exports = {
async headers() {
return [
{
source: '/api/:path*',
headers: [
{ key: 'Access-Control-Allow-Origin', value: '*' },
],
},
]
},
}
デプロイ後にページが古いデータを表示
重大度: 中
状況: 新しいデプロイメント後、更新されたデータが表示されない
症状:
- デプロイ後も古いコンテンツが表示される
- 変更がすぐに見えない
- 異なるユーザーが異なるバージョンを見ている
- データは更新されるがページは更新されない
なぜこれが問題か: Vercel は積極的にキャッシュします。静的ページはエッジでキャッシュ されます。動的ページでも適切に設定されていないとキャッシュされる ことがあります。キャッシュが期限切れになるか削除されるまで、古い キャッシュ版が提供されます。
推奨される対処:
キャッシュ動作を制御:
// キャッシュなし (常に新鮮)
export const dynamic = 'force-dynamic'
export const revalidate = 0
// ISR - 60秒ごとに再検証
export const revalidate = 60
// 変更後にオンデマンド再検証
import { revalidatePath, revalidateTag } from 'next/cache'
// Server Actionで:
async function updatePost(id: string) {
await db.post.update({ ... })
revalidatePath(`/posts/${id}`) // このページをパージ
revalidateTag('posts') // これでタグ付けされたすべてをパージ
}
// API経由でパージ (デプロイメントフック):
// POST https://your-site.vercel.app/api/revalidate?path=/posts
// レスポンスヘッダーでキャッシュを確認:
// x-vercel-cache: HIT = キャッシュから提供
// x-vercel-cache: MISS = 新規に生成
検証チェック
NEXT_PUBLIC 変数に機密情報
重大度: 重大
メッセージ: NEXT_PUBLIC_プレフィックスで機密情報が公開されています。ブラウザで表示されます。
対処: NEXT_PUBLIC_プレフィックスを削除してサーバー側コードでのみアクセス
Vercel URL のハードコード
重大度: 警告
メッセージ: Vercel URL がハードコードされています。代わりに VERCEL_URL 環境変数を使用してください。
対処: process.env.VERCEL_URL または NEXT_PUBLIC_VERCEL_URL を使用
Edge ランタイムでの Node.js API
重大度: エラー
メッセージ: Edge ランタイムで Node.js モジュールが使用されています。Edge では fs/path が利用できません。
対処: runtime = 'nodejs' を使用するか、Node.js の依存関係を削除
CORS ヘッダーなしの API ルート
重大度: 警告
メッセージ: CORS ヘッダーなしの API ルート。クロスオリジンリクエストが失敗する可能性があります。
対処: API が他のドメインから呼び出される場合、Access-Control-Allow-Origin ヘッダーを追加
エラーハンドリングなしの API ルート
重大度: 警告
メッセージ: API ルートに try/catch がありません。ハンドルされないエラーは詳細なしで500を返します。
対処: try/catch でラップし、適切なエラーレスポンスを返す
静的コンテキストでの機密情報読み込み
重大度: 警告
メッセージ: サーバー機密がビルド時に読み込まれています。値はビルドに埋め込まれます。
対処: 機密情報アクセスをランタイムコードに移行するか、公開値には NEXT_PUBLIC_ を使用
大きなパッケージインポート
重大度: 警告
メッセージ: 大きなパッケージが読み込まれています。コールドスタートが遅くなる可能性があります。別案を検討してください。
対処: tree shaking対応のlodash-es を使用、moment の代わりにdate-fns、aws-sdk の代わりに @aws-sdk/client-* を使用
再検証設定なしの動的ページ
重大度: 警告
メッセージ: 再検証設定がない動的ページです。キャッシュ戦略を設定することを検討してください。
対処: export const revalidate = 60 (ISR用) または 0 (キャッシュなし) を追加
コラボレーション
委任トリガー
- next.js|app router|pages|server components -> nextjs-app-router (デプロイはNext.jsパターンが必要)
- database|supabase|backend -> supabase-backend (デプロイはデータベース設定が必要)
- auth|authentication|session -> nextjs-supabase-auth (デプロイは認証設定が必要)
- monitoring|logs|errors|analytics -> analytics-architecture (デプロイはモニタリングが必要)
本番ローンチ
スキル: vercel-deployment、nextjs-app-router、supabase-backend、nextjs-supabase-auth
ワークフロー:
1. アプリ設定 (nextjs-app-router)
2. データベース設定 (supabase-backend)
3. 認証設定 (nextjs-supabase-auth)
4. デプロイ (vercel-deployment)
CI/CD パイプライン
スキル: vercel-deployment、devops、qa-engineering
ワークフロー:
1. テスト自動化 (qa-engineering)
2. パイプライン設定 (devops)
3. デプロイ戦略 (vercel-deployment)
関連スキル
相性がよい: nextjs-app-router、supabase-backend
使用される場面
- ユーザーが言及または暗示: vercel
- ユーザーが言及または暗示: deploy
- ユーザーが言及または暗示: deployment
- ユーザーが言及または暗示: hosting
- ユーザーが言及または暗示: production
- ユーザーが言及または暗示: environment variables
- ユーザーが言及または暗示: edge function
- ユーザーが言及または暗示: serverless function
制限事項
- このスキルは上記で説明されたスコープに明確に適合するタスクにのみ使用してください。
- 出力を環境固有の検証、テスト、またはエキスパートレビューの代替にしないでください。
- 必要な入力、権限、セーフティ境界、または成功基準が不足している場合は、立ち止まって説明を求めてください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- sickn33
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/sickn33/antigravity-awesome-skills / ライセンス: MIT
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。