開発からデプロイメントまで:EdgeOne Pages における Next.js フルスタックのベストプラクティス

Ethan MercerEthan Mercer
10 分読む
Spt 8, 2025

このガイドでは、高性能なNext.jsフルスタックアプリケーションの構築と、コード品質やアプリケーション速度を犠牲にすることなく開発ワークフローの最適化に焦点を当てています。

今後のセクションでは、プロジェクトアーキテクチャ、環境設定、ルーティング戦略、効率的なデータ取得技術について詳しく検討します。これらのストプラクティスにより、EdgeOne PagesでシームレスにNext.jsフルスタックアプリケーションをデプロイでき、エッジコンピューティングの力を活用して優れたパフォーマンスと世界規模のアクセシ。

ディレクトリ構造の推奨事項

以下のディレクトリ構造は、推奨するNext.jsハイブリッドレンダリングテンプレートを表しています。この慎重に整理されたアーキテクチャは、スケーラブルなフルスタックアプリケーションを構築する開発者にとって最適な基盤として機能します:

next-mix-template/
├── src/                   # Next.js App Router
│   │   ├── layout.tsx     
│   │   ├── page.tsx       # ホームページコンポーネント
│   │   ├── ssr/           # SSRデモンストレーションページ
│   │   ├── isr/           # ISRデモ
│   │   ├── ssg/           # SSGデモンストレーションページ
│   │   ├── streaming/     # ストリーミングデモンストレーションページ
│   │   ├── node-functions/# node function デ
│   │   ├── edge-functions/# edge function デモンストレーションページ
│   │   ├── api/           # APIルート
│   │   └── globals.css    # Reactコンポーネント
│   │   ├── ui/           
│   │   ├── Header.tsx    
│   │   ├── Hero.tsx      
│   │   ├── Features.tsx  
│   │   └── FeatureCard.tsx 
│   └── lib/              # ユーティリティ関数
├的リソース
├── package.json          # プロジェクト設定
├── next.config.ts        # Next.js設定
├── tailwind.config.ts    
└── components.json       # shadcn/ui設

このプロジェクトは、EdgeOne Pagesとシームレスに統合する2つの専用バックエンド function ディレクトリを持つ標準的なNext.js App Routerアーキテクチャに従っています:

edge-functionsディレクトリは、EdgeOne Pagesのエッジコンピューティング機能のエントリーポイントとして機能します。軽量なリクエストをここに配置することで、ユーザーに最も近いエッジノードから直接実行されるため、高速な応答時間の恩恵を受け、優れた速度とパフォーマンスを実現できます。

EdgeOne Pagesはnode-functionsを提ており、これは豊富なNode.jsパッケージエコシステムを活用できる集中型 function デプロイメント環境です。これに全なNode.js機能を必要とするより複雑な機能を迅速に実装でき、同時に合理化された開発体験を維持できます。

edge-functionsとnode-functionsの詳細については、公式ドキュメントをご参照ください。

ルートとAPI統合

EdgeOne Pagesでは、ドメインベースのパスルーティングを介してページとAPIエンドポイントに直接アクセスできます。マッピングは一貫したパターンに従い、ファイルの場所がURLパ直接対応します。例えば、/app/node-functions/get-users/index.js{domain}/get-usersでアクセス可能になります。

このプラットフォームは、自動パスマッピングを備えた直感的な特徴としています:

主な機能:

  • 自動パスマッピング:ファイルシステム構造がURLルートに直接変換されます
  • ゼロ設定:手動でのルーティング設定は不要です
  • 統一ルート管理:ページとAPIルートの両方をシームレスに処理します
  • ポートフリーアクセス:直接ドメインベースルーティングによりポート指定が不要です
Project structure:
/app/node-functions/get-users/index.js
/app/node-functions/create-user/index.js
/app/node-functions/products/[id].js
/app/edge-functions/get-products/index.js (edge)

Access method:
https://yourdomain.com/get-users      → run get-users/index.js
https://yourdomain.com/create-user    → run create-user/index.js
https://yourdomain.com/products/123   → run products/[id].js
https://yourdomain.com/get-products   → run get-products/index.js (edge)

ページレンダリングとデータ取得

Next.jsは複数のレンダリング戦略を提供し、それぞれ異なるデータ取得メカニズムを持っています。EdgeOne PagesはNext.jsの3つの主要なレンダリングモード(静的サイト生成(SSG)、サーバーサイドレンダリング(SSR)、インクリメンタル静的再生成(ISR))を包括的にサポートし、開発者が同じアプリケーション内ですべてのアプローチを活用できます。

1. App Routerデータ取得(Next.js 13+)

新しいApp Routerは、データ取得に異なるアプローチを採用しています。詳細については、Next.jsの公式ドキュメントをご覧ください。

// app/products/page.js
// デフォルトの静的レンダリング
async res = await fetch('https://api.example.com/products',: 'force-cache' // デフォルトキャッシュ
  })
  return res.json()
}

export default async function ProductsPage() {
  const products = await getProducts()
  
  return (
    <div>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  )
}

revalidate: 0を設定すると、毎回のリクエストでデータ取得にサーバーサ使用することが強制されます。

// app/live/page.js
// 動的レンダリング(getServerSidePropsに類似)
async function getLiveData() {
  const res = await fetch('https://api.example.com/live', {
    cache: 'no-store', // キャッシュなし、各リクエストで新しいデータを取得
    // または次を使用
    next: { revalidate: 0 }
  })
  return res.json()
}

// App RouterでのISR
async function getDataWithISR() {
  const res = await fetch('https://api.example.com/data', {
    next: { revalidate: 60 } // 60秒後に再検証
  })
  return res.json()
}
// pages/dashboard.js
// 静的とクライアントサイドデータ取得の組み合わせ
export async function getStaticProps() {
  // あまり変更されないデータを取得
  const staticData = await fetch('https://api.example.com/config')
  const

  return {
    props: { config },
    revalidate: 3600, // 1時間
  }
}

function Dashboard({ config }) {
  // クライアントがリアルタイムデータを取得
  const { data: liveData } = useSWR('/api/live-stats', fetcher, {
    refreshInterval: 5000
  })

  return (
    <div>
      <h1>{config.title}</h1>
      {liveData && <div>オンラインユーザー: {liveData.onlineUsers}</div>}
    </div>
  )
}

2. getStaticProps(静的生成)

ビルドプロセス中にデータを取得し、静的なHTMLページを生成します。比較的安定しており、頻繁な更新を必要としないコンテンツに最適です。

// pages/products.js
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/products')
  const products = await res.json()

  return {
    props: {
      products,
    }
  }
}

export default function Products({ products }) {
  return (
    <div>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  )
}

3. getServerSideProps(サーバーサイドレンダリング)

サーバーサイドレンダリング(SSR)は、毎回のリクエストでサーバーサイドでデータを取得します。この方法は、リアルタイムデータの更新やリクエスト固有の情報へのアクセスが必要なページに最適です。

// pages/user/[id].js
export async function getServerSideProps(context) {
  const { id } = context.params
  const { req, res, query } = context
  
  const cookies = context.req.cookies
  
  const userData = await fetch(`https://api.example.com/users/${id}`)
  const user = await userData.json()

  if (!user) {
    return {
      notFound: true, 
    }
  }

  return {
    props: {
      user,
    }
  }
}

export default function User({ user }) {
  return <div>Welcome, {user.name}!</div>
}

使用例:LinkedIn(linkedin.com

4. ISR(インクリメンタル静的再生成)

revalidateパラメータは、インクリメンタル静的再生成(ISR)を有効にし、ルールベースのオンデマンドページデータ更新を提供します。

export async function getStaticProps() {
  const res = await fetch('https://api.example.com/blog')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Three ISR strategies
    revalidate: 60, // Regenerate after a time interval in seconds
    // or
    revalidate: false, // Disable ISR and only generate it at build time
    // or
    revalidate: true, // On-demand ISR (configuration required)
  }
}

使用例:Dev.to(dev.to人気コンテンツは5分ごとに更新

方法の比較と決定マトリックス

方法実行時間使用例SEOパフォーマンス
getStaticPropsビルド時静的コンテンツ✅ 優秀⚡ 最速
getServerSideProps毎回のリクエスト動的コンテンツ/パーソナライゼーション✅ 良好🐢 低速
ISR (revalidate)ビルド時 + 定期更新半静的コンテンツ✅ 良好⚡ 高速
App Router fetch設定に依存柔軟✅ 良好🔧 設定可能

開発者向け決定マトリックス:

ウェブサイトタイプ推奨戦略代表的サイト主な考慮事項
ドキュメント/ブログSSGNext.js Docs, MDNSEO、パフォーマンス、コスト
EコマースプラットフォームSSR/ISRAmazon, Shopifyリアルタイム在庫、パーソナライゼーション
ソーシャルメディアSSRTwitter, LinkedInリアルタイム更新、パーソナライゼーション
ニュースメディアISR/SSRCNN, BBCタイムリー性、SEO
SaaSマーケティングサイトSSG/ISRStripe, Slackパフォーマンス、コンバージョン率
企業ウェブサイトSSGApple, Microsoftブランドプレゼンテーション、パフォーマンス
オンライン教育ISRCoursera, Udemyコンテンツ更新、SEO
ストリーミングメディアSSRNetflix, Spotifyパーソナライゼーション、リアルタイムレコメンデーション

環境変数管理

EdgeOne Pagesは環境変数管理の規約に準拠しています:

  • パブリック変数:`NEXT_PUBLIC_`プレフィックスが付いた環境変数は、クライアントサイドバンドルに埋め込まれ、ブラウザコードでアクセス可能になります。これらの変数には、機密でない情報のみを含める必要があります。
  • 保護された変数:APIキー、認証トークン(例:`AI_TOKEN`)、その他の認証情報などの機密情報については、`NEXT_PUBLIC_`プレフィックスを省略します。これらの変数はサーバーサイドのみに留まり、クライアントサイドコードでの露出から保護されます。

この一貫した準的なNext.js環境変数システムとの互換性を維持しながら、設定値の可視性とセキュリティを管理できます。

# プライベート環境変数

OPENAI_API_URL=
OPENAI_API_KEY=

DB_HOST=
DB_PORT=
DB_USER=
DB_PASSWORD=
DB_NAME=

# パブリック環境変数
NEXT_PUBLIC_AUTHOR=
NEXT_PUBLIC_EMAIL=

通常、単一の.env.localファイルで十分です。ただし、開発環境(next dev)や本番環境(next start)に対して、それぞれ別途デフォルト設定を追加したい場合があります。

Next.jsでは、.env(全環境用)、.env.development (開発環境用)、.env.production(本番環境用)でデフォルト値を設定できます。.env.localは常にデフォルト設定を上書きします。

EdgeOne Pagesにデプロイする際は、ローカルの.envファイルと一致する環境変数をEdgeOneコンソールで設定する必要があります。EdgeOne PagesはNext.jsの規約に従い、NEXT_PUBLIC_のプレフィックスが付いた変数はクライアントサイドのコードに埋め込まれ、このプレフィックスがない変数はサーバーサイドで保護されたままになります。 

注意:セキュリティのため、APIキーやトークンなどの機密情報が誤ってリポジトリにコミットされることを防ぐために>env*ファイルを.gitignoreに追加してください。

まとめ

EdgeOne PagesはNext.jsフルスタックプロジェクトに対して包括的なネイティブサポートを提供し、静的サイト生成(SSG)、サーバーサイドレンダリング(SSR)、インクリメンタル静的再生成(ISR)、API Routesなど、様々なNext.jsのコア機能と完全に互換性があります。開発者は複雑な設定調整を行うことなく、Next.jsフレームワークのすべての利点を活用でき、柔軟なレンダリング戦略の選択と効率的なフルスタック開発体験を可能にします。

EdgeOne Pagesの効率的なデプロイメントプロセスのおかげで、開発チームはEdgeOne CLI操作やCI/CD統合を通じて、Next.jsアプリケーションをグローバルエッジネットワークに迅速にデプロイできます。このシームレスなデプロイメント体験は、運用の複雑さを大幅に削減するだけでなく、エッジコンピューティング機能を通じて優れたパフォーマンスと信頼性を提供し、開発者がインフラ管理と最適化を心配することなく、ビジネスロジックの実装により集中できるようにします。