Vercel

WebホスティングJAMstackエッジファンクションCI/CDフロントエンドNext.jsReactVueSvelte

Webホスティングプラットフォーム

Vercel

概要

Vercelは、Next.jsの開発元が提供するWebアプリケーション・API・静的サイト向けクラウドプラットフォームです。ゼロ設定でのデプロイ、エッジファンクション、プレビューデプロイ機能により、フロントエンド開発者の間で最も人気の高いプラットフォームとなっています。特にNext.js、React、Vueなどのフレームワークとの最適化が進んでおり、エッジコンピューティング分野をリードしています。

詳細

Vercelは2015年に設立されたNext.jsの開発元として、モダンなWebアプリケーション開発に特化したクラウドプラットフォームを提供しています。フロントエンドに特化した設計により、Git連携による自動デプロイ、プレビューURL生成、Edge Functions、高速CDN、分析機能などを統合的に提供。開発者体験を最重視した設計により、コードプッシュから本番環境への反映まで数秒で完了し、チーム開発におけるプレビュー機能も充実しています。Cloudflareの競合として、エッジコンピューティングやパフォーマンス最適化技術の開発も積極的に進めています。

メリット・デメリット

メリット

  • ゼロ設定デプロイ: 設定不要でGit連携による自動デプロイが可能
  • 高速エッジネットワーク: グローバルに分散されたCDNによる超高速配信
  • プレビュー機能: Pull Request毎に一意のプレビューURLを自動生成
  • フレームワーク最適化: Next.js、React、Vue等との深い統合と最適化
  • Edge Functions: 低レイテンシのサーバーサイド処理が可能
  • 豊富な分析機能: Web Analytics、Speed Insights等の詳細なパフォーマンス分析
  • 優秀な開発者体験: 直感的なダッシュボードと包括的なドキュメント

デメリット

  • 価格が高め: 大規模サイトやチーム利用時のコストが高額
  • ベンダーロックイン: Vercel特有の機能に依存するとマイグレーションが困難
  • 制限事項: 実行時間、メモリ、ファイルサイズなどの制限
  • 日本語サポート: 公式の日本語サポートが限定的

参考ページ

書き方の例

基本的なセットアップとプロジェクト設定

# Vercel CLIのインストール
npm install -g vercel@latest

# プロジェクトの初期化とリンク
vercel link

# 環境変数の設定
vercel env add NEXT_PUBLIC_API_URL

# 開発環境での実行
vercel dev

静的サイトデプロイ

{
  "name": "my-static-site",
  "version": "2",
  "builds": [
    {
      "src": "package.json",
      "use": "@vercel/static-build",
      "config": {
        "distDir": "dist"
      }
    }
  ],
  "routes": [
    {
      "handle": "filesystem"
    },
    {
      "src": "/(.*)",
      "dest": "/index.html"
    }
  ]
}

フレームワーク統合(Next.js、React、Vue)

// next.config.js - Next.js最適化設定
/** @type {import('next').NextConfig} */
const nextConfig = {
  // Vercel向け最適化
  output: 'standalone',
  
  // Edge Runtime設定
  experimental: {
    runtime: 'edge',
  },
  
  // 画像最適化
  images: {
    domains: ['example.com'],
    formats: ['image/webp', 'image/avif'],
  },
  
  // ヘッダー設定
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 's-maxage=1, stale-while-revalidate=59',
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;
# Vue.js プロジェクトのデプロイ
npx create-vue@latest my-vue-app
cd my-vue-app
npm install
npm run build
vercel deploy

カスタムドメインとSSL

# カスタムドメインの追加
vercel domains add example.com

# ドメインの設定確認
vercel domains ls

# SSL証明書の自動設定(Let's Encrypt)
# Vercelでは自動的にSSL証明書が発行される
// vercel.json - カスタムドメイン設定
{
  "github": {
    "enabled": false
  },
  "functions": {
    "app/api/**/*.js": {
      "runtime": "nodejs18.x"
    }
  },
  "routes": [
    {
      "src": "/(.*)",
      "dest": "/app/$1"
    }
  ],
  "headers": [
    {
      "source": "/api/(.*)",
      "headers": [
        {
          "key": "Access-Control-Allow-Origin",
          "value": "https://example.com"
        }
      ]
    }
  ]
}

サーバーレスファンクションとAPI

// api/hello.js - 基本的なサーバーレスファンクション
export default function handler(req, res) {
  const { name = 'World' } = req.query;
  
  res.setHeader('Cache-Control', 's-maxage=1, stale-while-revalidate=59');
  res.status(200).json({
    message: `Hello ${name}!`,
    timestamp: new Date().toISOString()
  });
}
// api/users/[id].ts - 動的ルーティング
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { id } = req.query;
  
  if (req.method === 'GET') {
    // ユーザー情報の取得
    const user = await getUserById(id as string);
    res.status(200).json(user);
  } else if (req.method === 'PUT') {
    // ユーザー情報の更新
    const updatedUser = await updateUser(id as string, req.body);
    res.status(200).json(updatedUser);
  } else {
    res.setHeader('Allow', ['GET', 'PUT']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

CI/CDと本番最適化

# .github/workflows/deploy.yml
name: Deploy to Vercel
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          cache: 'npm'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Build project
        run: npm run build
      
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'
// middleware.js - Edge Middleware
import { NextResponse } from 'next/server';
import { geolocation } from '@vercel/functions';

export function middleware(request) {
  // 地理情報に基づくリダイレクト
  const { country } = geolocation(request);
  
  if (country === 'JP') {
    return NextResponse.rewrite(new URL('/ja', request.url));
  }
  
  // A/Bテスト
  const bucket = Math.random() < 0.5 ? 'a' : 'b';
  const response = NextResponse.next();
  response.cookies.set('bucket', bucket);
  
  return response;
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};
# パフォーマンス最適化コマンド
vercel inspect    # デプロイメント詳細の確認
vercel logs       # ログの確認
vercel analytics  # 分析データの表示

# 本番環境への手動デプロイ
vercel --prod

# 特定のリージョンへのデプロイ
vercel --regions iad1,hnd1