デザインについての学習メモブログ

Next.js入門:アプリケーションを本番公開方法-Vercelへデプロイ

記事内に広告が含まれています。

Next.js入門:アプリケーションを本番公開方法-Vercelへデプロイ

Next.jsアプリケーションを開発したら、次は世界中の人に使ってもらえるよう公開を考えるのが一般的でしょう。

Vercelは、Next.jsの開発元であるVercel社が提供するホスティングプラットフォームで、Next.jsアプリケーションを最も簡単かつ効率的に公開できるサービスです。

この記事では、Vercelを使ってNext.jsアプリケーションを公開する方法を、基本的な設定から高度な機能まで詳しく解説します。

Vercelへデプロイのための基礎知識

なぜVercelを選ぶのか?

Vercelの主なメリット

  • ゼロ設定デプロイ: 複雑な設定なしで即座にデプロイ可能
  • グローバルCDN: 世界中で高速なコンテンツ配信
  • 自動スケーリング: トラフィックに応じた自動スケール
  • プレビューデプロイ: Pull Request毎にプレビュー環境を自動生成
  • 豊富な無料枠: 個人プロジェクトには十分な無料プラン
  • Next.js最適化: Next.jsに特化した最適化が自動適用

料金体系

  • Hobby(無料): 個人プロジェクト向け
  • Pro(月20ドル〜): チーム・商用利用
  • Enterprise: 大規模企業向け

Vercelへデプロイまでの手順

Step 0:事前準備

必要なアカウント

  1. GitHubアカウント: ソースコード管理用
  2. Vercelアカウント: デプロイ用(GitHubアカウントで登録可能)

プロジェクトの要件

Next.jsプロジェクトが以下の要件を満たしていることを確認してください。

JSON
// package.json
{
  "name": "my-next-app",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "^14.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}

もし、学習用にプロジェクトがない場合

以下の記事を参考に学習用のプロジェクトを作成してください。

デフォルトのページ(page.tsx)を少し変えておくと自分のプロジェクトが公開できたか区別しやすくなります。

Step 1: GitHubリポジトリの準備

新規プロジェクトの場合

  • 事前にGitHub上にリモートレポジトリを作成しておく
  • githubにSSHキーを登録しておく
Bash
# プロジェクトディレクトリに移動
cd my-next-app

# Gitリポジトリを初期化
git init

# .gitignoreファイルを確認・作成 !!!ファイルがあれば不要!!!
echo "node_modules/
.next/
.env*.local
.vercel
*.log" > .gitignore

# 初回コミット
git add .
git commit -m "Initial commit"

# GitHubでリポジトリを作成後、リモートを追加
# https://github.com/username/my-next-app.git の”username”はご自身のユーザー名になります。
git remote add origin https://github.com/username/my-next-app.git
git branch -M main
git push -u origin main

リモートレポジトリのアドレス登録を間違えた場合は、以下のコマンドで一旦削除し、自分のリモートレポジトリのurlを追加し直してください。

Bash
#間違えて git remote addで登録されたurlを確認
git remote -v 
#間違えたremoteを削除
git remote remove origin
#間違えたremoteが削除された確認
git remote -v 

既存プロジェクトの場合

最新の変更をGitHubにプッシュする。

Bash
git add .
git commit -m "Ready for deployment"
git push origin main

Step 2: Vercelアカウントの作成

  1. vercel.comにアクセス
  2. 「Sign up」をクリック
  3. 「Continue with GitHub」を選択してGitHubアカウントで登録
  4. 必要な権限を許可
    • 3を実行後、GitHubのOAuth承認画面が表示される
    • この画面でVercelが要求する権限(リポジトリアクセス、チェック機能、コンテンツの読み書きなど) Vercelの一覧が表示される
    • ユーザーが「Authorize Vercel」ボタンをクリックして許可する

Step 3: プロジェクトのインポート

Webダッシュボードから

  1. Vercelダッシュボードで「Add New Project」をクリック
  2. GitHubから対象のリポジトリを選択
    • レポジトリ選択後、install
  3. 「Import」をクリック

自動検出される設定

Vercelは自動的に以下を検出・設定します。

デプロイが完了するまで待つだけです。

  • Framework: Next.js
  • Build Command: npm run build
  • Output Directory: .next
  • Install Command: npm install

Step 4:公開されたサイトを確認

Vercelダッシュボードで対象プロジェクトを開くと、Deployments というセクションがあります。

  1. 最新のデプロイが ✅ Ready(緑色)になっていれば正常にデプロイされています。
  2. エラー(赤マーク)がある場合はログを確認する必要があります。
  3. デプロイが成功していれば、Vercelが自動で割り当てたURLが表示されます。
  4. 例:https://your-project-name.vercel.app
  5. このURLにアクセスして、Webサイトが表示されれば 公開完了 です。

まずは、ここまでできれば、一般公開した状態での成果物を確認できます。

以降については、さらに使いこなすためにできる事をざっくり解説しています。

継続的に開発→デプロイの流れや独自ドメインの設定も紹介しています。

Vercelへデプロイ後に役立ち機能

継続的デプロイの設定

自動デプロイの仕組み

Vercelは以下のタイミングで自動デプロイを実行:

  • Production: mainブランチへのプッシュ
  • Preview: Pull Requestの作成・更新

ブランチベースの環境設定(ローカルで本番用レポジトリにマージ後プッシュ)

個人開発であればこれでも良い

Bash
# 開発用ブランチ
git checkout -b feature/new-feature
git push origin feature/new-feature
# → プレビュー環境が自動生成

# 本番リリース
git checkout main
git merge feature/new-feature
git push origin main
# → 本番環境が自動更新

GitHub Actionsとの連携(オプション)

公開前に自動テストも行えてサービスの品質を維持しやすい

YAML
# .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@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run tests
        run: npm test
        
      - name: Build application
        run: npm run build

環境変数の設定

環境変数が必要な場合

プロジェクトで環境変数を使用している場合は

  1. プロジェクト設定ページの「Environment Variables」タブ
  2. 変数名と値を入力
  3. 環境(Production, Preview, Development)を選択
  4. 「Add」をクリック
Bash
# ローカルの .env.local(例)
DATABASE_URL=postgresql://localhost/myapp
NEXTAUTH_SECRET=your-secret-key
NEXT_PUBLIC_API_URL=https://api.example.com

Vercelでの設定例

Bash
Name: DATABASE_URL
Value: postgresql://production-db-url
Environment: Production

Name: NEXTAUTH_SECRET
Value: production-secret-key
Environment: Production, Preview

Name: NEXT_PUBLIC_API_URL
Value: https://api.example.com
Environment: Production, Preview, Development

カスタムドメインの設定

独自ドメインを使用する場合

  1. プロジェクト設定の「Domains」タブ
  2. 「Add」をクリックしてドメイン名を入力
  3. DNS設定の指示に従って設定
Aレコード設定例
Bash
Type: A
Name: @
Value: 76.76.19.61

Type: CNAME  
Name: www
Value: cname.vercel-dns.com

name: @の部分は未入力で良い場合もある

サブドメインの設定の場合

Bash
# 例:blog.example.com
Type: CNAME
Name: blog
Value: cname.vercel-dns.com

ビルドとデプロイの最適化

JSON
{//vercel.jsonファイルでの詳細設定
  "buildCommand": "npm run build",
  "outputDirectory": ".next",
  "installCommand": "npm ci",
  "functions": {
    "pages/api/**/*.js": {
      "maxDuration": 30
    }
  },
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        }
      ]
    }
  ],
  "rewrites": [
    {
      "source": "/api/:path*",
      "destination": "https://api.example.com/:path*"
    }
  ],
  "redirects": [
    {
      "source": "/old-page",
      "destination": "/new-page",
      "permanent": true
    }
  ]
}

Next.js設定の最適化

JavaScript
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // 画像最適化
  images: {
    domains: ['example.com', 'cdn.example.com'],
    formats: ['image/webp', 'image/avif'],
  },
  
  // 圧縮設定
  compress: true,
  
  // 静的エクスポート(必要に応じて)
  output: 'standalone',
  
  // 実験的機能
  experimental: {
    // App Routerを使用する場合
    appDir: true,
  },
  
  // 環境変数
  env: {
    CUSTOM_KEY: process.env.CUSTOM_KEY,
  },
}

module.exports = nextConfig

セキュリティの設定

セキュリティヘッダー

Webサイトを公開するときに、悪意ある攻撃や情報漏えいを防ぐための安全ルールを、ブラウザに伝える仕組みです。

JavaScript
// vercel.json
{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Strict-Transport-Security",
          "value": "max-age=31536000; includeSubDomains"
        },
        {
          "key": "Content-Security-Policy",
          "value": "default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'"
        }
      ]
    }
  ]
}
🧱 1. “source”: “/(.*)”

→ 「すべてのページ」にこの設定を適用するという意味です。

(/(.*) は “すべてのURLにマッチ” という正規表現)

🔒 2. “Strict-Transport-Security”

→ HTTPS接続を強制するルールです。

「このサイトは常に安全な通信(HTTPS)でアクセスしてね」 とブラウザに伝えます。

  • max-age=31536000 → このルールを「1年間(31536000秒)」覚えておく
  • includeSubDomains → サブドメイン(例: blog.example.com)にも適用する

🟢 これで「http://」でアクセスしても、自動で「https://」に変わります。

🛡️ 3. “Content-Security-Policy”(CSP)

→ サイトにどこからのスクリプトやスタイルを読み込んでいいかを指定するルール。

  • default-src ‘self’  → 基本的に、自分のサイト(同じドメイン)からのファイルだけを許可。
  • script-src ‘self’ ‘unsafe-eval’ ‘unsafe-inline’  → JavaScriptは自分のサイト内のものOK。   ’unsafe-inline’ と ‘unsafe-eval’ は「安全ではないけど一部の開発用スクリプトを許可」という意味。   本番環境ではできるだけ外したほうが安全です。
  • style-src ‘self’ ‘unsafe-inline’  → CSSも自分のサイト内のものだけOK。
    ‘unsafe-inline’ は <style>タグ内に直接書かれたCSSも許可します。

パフォーマンス最適化のベストプラクティス

1. コード分割の活用

JavaScript
// 動的インポート
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() => import('../components/Heavy'), {
  loading: () => <p>Loading...</p>,
  ssr: false, // クライアントサイドのみで実行
})

2. 画像最適化

JavaScript
import Image from 'next/image'

function MyComponent() {
  return (
    <Image
      src="/hero.jpg"
      alt="Hero image"
      width={800}
      height={600}
      priority // Above-the-fold画像に設定
      placeholder="blur"
      blurDataURL="data:image/jpeg;base64,..."
    />
  )
}

3. フォントの最適化

JavaScript
// pages/_app.js
import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export default function App({ Component, pageProps }) {
  return (
    <main className={inter.className}>
      <Component {...pageProps} />
    </main>
  )
}

監視とデバッグ

ログの確認

Vercelダッシュボードの「Functions」タブでサーバーサイドのログを確認できます。

JavaScript
// pages/api/debug.js
export default function handler(req, res) {
  console.log('Request method:', req.method)
  console.log('Request headers:', req.headers)
  console.log('Request body:', req.body)
  
  res.status(200).json({ message: 'Debug info logged' })
}

パフォーマンス監視

  1. ダッシュボードの「Analytics」タブ
  2. Web Vitalsメトリクスの確認
  3. 地域別パフォーマンスの分析

エラー監視の設定

JavaScript
// pages/_app.js
import * as Sentry from '@sentry/nextjs'

// Sentryの初期化
Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
})

export default function App({ Component, pageProps }) {
  return <Component {...pageProps} />
}

アナリティクス設定

Vercel Analyticsは、Vercelが提供する軽量なWebアナリティクスサービスで、プライバシーに配慮しながらサイトのパフォーマンスとユーザー行動を追跡できます。

JavaScript
// pages/_app.js
import { Analytics } from '@vercel/analytics/react'

export default function App({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <Analytics />
    </>
  )
}

Speed Insights

Vercel Speed Insightsは、実際のユーザー環境でのWebサイトのパフォーマンスを測定し、Core Web Vitalsを収集・分析するツールです。

JavaScript
// pages/_app.js
import { SpeedInsights } from '@vercel/speed-insights/next'

export default function App({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <SpeedInsights />
    </>
  )
}

高度な機能の活用

Edge Functions

Edge Functionsは、ユーザーに最も近い地理的な場所(エッジサーバー)で実行されるサーバーレス関数です。

世界中に分散されたエッジロケーションで実行されるため、ユーザーに最も近いサーバーから応答が返され、レスポンスが高速になります。

JavaScript
// pages/api/edge-example.js
export const config = {
  runtime: 'edge',
}

export default function handler(req) {
  return new Response(
    JSON.stringify({ 
      message: 'Hello from Edge Function!',
      timestamp: new Date().toISOString()
    }),
    {
      status: 200,
      headers: {
        'content-type': 'application/json',
      },
    }
  )
}

ISR(Incremental Static Regeneration)

ISRは、Next.jsの機能で、静的生成されたページを本番環境で段階的に更新できる仕組みです。

ビルド時に全ページを生成する必要がなく、アクセスに応じて動的に生成・更新できます

JavaScript
// pages/blog/[slug].js
export async function getStaticProps({ params }) {
  const post = await fetchPost(params.slug)
  
  return {
    props: { post },
    // 60秒後に再生成
    revalidate: 60,
  }
}

export async function getStaticPaths() {
  const posts = await fetchAllPosts()
  
  return {
    paths: posts.map((post) => ({
      params: { slug: post.slug }
    })),
    fallback: 'blocking',
  }
}

トラブルシューティング:よくある問題と解決策

問題1: ビルドが失敗する

Bash
# ローカルでビルドをテスト
npm run build

# 依存関係の問題を確認
npm ls

# キャッシュをクリア
rm -rf .next node_modules package-lock.json
npm install
npm run build

問題2: 環境変数が読み込まれない

  • Vercelダッシュボードで環境変数が正しく設定されているか確認
  • NEXT_PUBLIC_プレフィックスがクライアントサイドで必要な変数に付いているか確認
  • 設定後に再デプロイが必要

問題3: API Routesがタイムアウトする

JSON
// vercel.json
{
  "functions": {
    "pages/api/**/*.js": {
      "maxDuration": 60
    }
  }
}

問題4: 画像最適化が動作しない

JSON
// next.config.js
module.exports = {
  images: {
    domains: ['your-domain.com'],
    // または外部画像を無効化
    unoptimized: true,
  },
}

まとめ

Vercelを使ったNext.jsアプリケーションの公開は、初期設定から高度な機能まで非常に簡単に実現できます。

この記事で学んだこと

  • 簡単デプロイ: GitHubとの連携で自動デプロイ
  • グローバル配信: 世界中で高速なアクセス
  • 自動最適化: Next.jsに特化した最適化
  • 豊富な機能: Edge Functions、ISR、アナリティクスなど
  • セキュリティ: HTTPS、セキュリティヘッダーの自動設定

推奨する次のステップ

  1. データベース統合: PlanetScale、Supabaseなどの統合
  2. 認証システム: NextAuth.jsの導入
  3. CMS連携: Contentful、Strapiなどとの連携
  4. モニタリング: Sentry、LogRocketなどの導入
  5. テスト自動化: Cypress、Jestでのテストパイプライン構築

Vercelの無料プランでも多くの機能が利用できるので、まずは小さなプロジェクトから始めて、徐々に高度な機能を活用していきましょう。

参考リンク