CONTENT
ここから
この章でわかること
この章では、Next.jsでECサイトを作るときの基本設計を整理します。
Squareは決済を担当します。
では、Next.jsは何を担当するのでしょうか。
答えは、主に次の部分です。
商品ページを表示する
商品一覧を表示する
購入ボタンを置く
Square APIを呼び出す
注文処理を行う
決済完了ページを表示する
Webhookを受け取る
SEOに強いページを作る
管理画面を作る
つまり、Next.jsはECサイトの「表側」と「裏側の一部」を担当します。
攻略本のように考えるなら、Next.jsはECサイトの街そのものです。
トップページ
商品ページ
カート
決済への入口
注文完了ページ
管理画面
API
これらを、Next.jsの機能を使って配置していきます。
3.1 App Routerを前提にしたEC構成
Next.jsで新しくECサイトを作る場合、本書ではApp Routerを前提にします。
App Routerは、Next.js 13から導入された新しいルーティング方式で、React Server Componentsを土台にしています。Next.js公式ドキュメントでも、App RouterはServer Componentsなど新しいReact機能をサポートする新しいルーターとして説明されています。(nextjs.org)
App Routerでは、appディレクトリの中にページやAPIを作ります。
たとえば、ECサイトなら次のような構成になります。
app
├─ page.tsx
├─ products
│ ├─ page.tsx
│ └─ [slug]
│ └─ page.tsx
├─ cart
│ └─ page.tsx
├─ checkout
│ └─ route.ts
├─ thank-you
│ └─ page.tsx
├─ api
│ └─ square
│ └─ webhook
│ └─ route.ts
└─ admin
└─ orders
└─ page.tsx
それぞれの役割は次の通りです。
| パス | 役割 |
|---|---|
/ | トップページ |
/products | 商品一覧ページ |
/products/[slug] | 商品詳細ページ |
/cart | カートページ |
/checkout | Square決済リンク作成API |
/thank-you | 決済完了ページ |
/api/square/webhook | SquareからのWebhook受信 |
/admin/orders | 管理画面の注文一覧 |
App Routerの良いところは、ページとAPIを同じappディレクトリ内で整理できることです。
画面もAPIも、ECサイトの導線に合わせて配置できます。
攻略ポイント
最初は、複雑なディレクトリ構成にしなくて大丈夫です。
まずは次の4つだけ作れば、最小構成のECになります。
商品一覧ページ
商品詳細ページ
決済リンク作成API
決済完了ページ
この4つが、最初のステージです。
3.2 Server ComponentとClient Componentの使い分け
Next.jsのApp Routerでは、Server ComponentとClient Componentを使い分けます。
名前だけ見ると難しそうですが、考え方はシンプルです。
Server Component
↓
サーバー側で処理してHTMLを作る部品
Client Component
↓
ブラウザ側で動く部品
Next.js公式ドキュメントでは、Server ComponentsとClient Componentsの使い分けについて、サーバー側でデータ取得やレンダリングを行う部分と、ブラウザ側でインタラクションを扱う部分を分けて説明しています。(nextjs.org)
ECサイトで考えると、次のように分けます。
Server Componentに向いているもの
商品一覧ページ
商品詳細ページ
カテゴリページ
FAQページ
ブログ記事
注文完了ページの初期表示
これらは、最初にページを表示する時点で必要な情報が決まっていることが多いです。
サーバー側で商品データを取得して、HTMLとして表示できます。
SEOにも向いています。
Client Componentに向いているもの
カートに追加ボタン
数量変更ボタン
モーダル
タブ切り替え
お気に入りボタン
フォーム入力
リアルタイムなUI
これらは、ユーザーがクリックしたり入力したりする部分です。
ブラウザ上で状態を持つ必要があるため、Client Componentにします。
ECでの基本方針
ECサイトでは、なるべくServer Componentを中心にします。
理由は、表示速度とSEOに有利だからです。
ただし、クリック操作や入力操作が必要な部分だけClient Componentにします。
商品説明
↓
Server Component
購入ボタン
↓
Client Componentまたはフォーム
カート数量変更
↓
Client Component
商品画像や説明の表示
↓
Server Component
攻略ポイント
迷ったら、次のように判断します。
ユーザー操作がない
↓
Server Component
クリック・入力・状態変更がある
↓
Client Component
最初から全部Client Componentにしないことが大切です。
全部をブラウザ側で動かすと、ページが重くなりやすく、SEOにも不利になる場合があります。
3.3 Route HandlersでAPIを作る
Route Handlersは、Next.jsの中にAPIを作るための仕組みです。
Next.js公式ドキュメントでは、route.tsまたはroute.jsを使って、指定したルートに対するカスタムリクエストハンドラーを作れると説明されています。対応するHTTPメソッドには、GET、POST、PUT、PATCH、DELETEなどがあります。(nextjs.org)
ECサイトでは、Route Handlersを次のような場面で使います。
Square APIを呼び出す
決済リンクを作成する
Webhookを受け取る
外部サービスと連携する
注文ステータスを更新する
たとえば、購入ボタンを押したときに、Next.js側でSquare APIを呼び出して決済リンクを作る場合があります。
この処理は、ブラウザ側ではなくサーバー側で行います。
理由は、SquareのAccess Tokenを守る必要があるからです。
ブラウザ側に出してはいけないもの
↓
Square Access Token
API Secret
DB接続情報
Webhook Secret
Route Handlerを使うと、次のような流れを作れます。
購入ボタンを押す
↓
Next.jsのRoute HandlerへPOSTする
↓
Route HandlerがSquare APIを呼ぶ
↓
Squareの決済リンクを受け取る
↓
ユーザーを決済ページへ移動させる
攻略ポイント
Route Handlersは、外部サービスとつながる門番です。
ユーザー画面
↓
Route Handler
↓
Square API
ユーザー画面から直接Square APIを呼ぶのではなく、必ずNext.jsのサーバー側を通します。
これが安全なEC設計の基本です。
3.4 Server Actionsで注文処理を書く
Server Actionsは、フォーム送信やデータ変更処理をサーバー側で実行するための仕組みです。
Next.js公式ドキュメントでは、Server Actionsはサーバー上で実行される非同期関数で、フォーム送信やデータ変更に使えると説明されています。(nextjs.org)
現在のNext.jsドキュメントでは、データ更新はReactのServer Functionsとして説明されており、フォーム送信やデータ変更処理に使う流れが案内されています。(nextjs.org)
ECサイトでは、Server Actionsを次のような処理に使えます。
カートに追加する
注文を作成する
配送先を保存する
クーポンを適用する
注文ステータスを変更する
管理画面から発送済みにする
ただし、SquareのWebhook受信のように外部サービスからHTTPリクエストが来る処理は、Route Handlerで扱うほうが自然です。
つまり、使い分けはこうです。
| 処理 | 向いている方法 |
|---|---|
| ユーザーのフォーム送信 | Server Actions |
| 管理画面の更新処理 | Server Actions |
| Square APIへの明示的なAPIエンドポイント | Route Handlers |
| Square Webhook受信 | Route Handlers |
| 外部サービスからのHTTP通知 | Route Handlers |
攻略ポイント
Server Actionsは、ユーザー操作をサーバー側で安全に処理する道具です。
Route Handlersは、外部サービスとの出入口です。
ユーザー操作
↓
Server Actions
外部サービス連携
↓
Route Handlers
この分け方を覚えておくと、設計がかなり整理されます。
3.5 商品ページを高速表示する設計
ECサイトで最も大切なページのひとつが、商品ページです。
商品ページが遅いと、ユーザーは購入前に離脱します。
特にスマートフォンでは、ページ表示の遅さがそのまま売上に影響します。
Next.jsで商品ページを高速表示するためには、次の考え方が重要です。
サーバー側で商品データを取得する
不要なJavaScriptを減らす
商品説明はServer Componentで表示する
画像を最適化する
更新頻度に応じてキャッシュする
商品ページは、毎秒変わるものではありません。
商品名、説明文、価格、画像などは、ある程度キャッシュできます。
一方で、在庫や販売状況は変わる可能性があります。
そのため、商品ページ全体を毎回動的にするのではなく、変わりやすい部分と変わりにくい部分を分けます。
変わりにくい情報
↓
商品名、説明文、画像、SEO本文
変わりやすい情報
↓
在庫、価格、販売ステータス
攻略ポイント
商品ページは、全部をリアルタイムにしようとしないことです。
最初は、次のように考えます。
商品説明
↓
高速表示を優先
在庫情報
↓
必要に応じて動的に確認
購入ボタン
↓
押された時点でサーバー側で確認
購入ボタンを押した時点で、価格や在庫をサーバー側で再確認すれば、表示ページ自体は高速化しやすくなります。
3.6 カート処理をどこに持たせるか
ECを作るとき、カート処理をどこに持たせるかは重要です。
主な選択肢は3つあります。
ブラウザ側
Cookie
サーバー側DB
ブラウザ側に持つ
localStorageやReactの状態でカートを持つ方法です。
実装は簡単ですが、ブラウザを変えると引き継げません。
また、カート内の価格や商品情報をそのまま信用してはいけません。
メリット
↓
実装が簡単
サーバー負荷が少ない
注意点
↓
改ざんされる可能性がある
別端末で引き継げない
Cookieに持つ
CookieにカートIDや簡単なカート情報を保存する方法です。
サーバー側で参照しやすく、未ログインユーザーにも対応しやすいです。
メリット
↓
サーバー処理と連携しやすい
未ログインでも使いやすい
注意点
↓
保存できる容量に限りがある
機密情報は入れない
サーバー側DBに持つ
カート情報をDBに保存する方法です。
会員機能や複数端末対応、本格的なECに向いています。
メリット
↓
本格的なカート管理ができる
会員機能と相性がよい
注意点
↓
実装が少し複雑になる
DB設計が必要
最初のおすすめ
最初は、カートなしでも構いません。
商品詳細ページに購入ボタンを置き、直接Square決済ページへ送る構成で十分です。
商品詳細ページ
↓
購入ボタン
↓
Square決済ページ
複数商品をまとめて購入したい要件が出てきたら、カートを追加します。
攻略ポイント
ECの最初のボスは、カート機能ではありません。
最初のボスは、
1商品を購入できる状態にすることです。
カートは第2ステージで大丈夫です。
3.7 キャッシュ、再検証、動的ページの考え方
Next.jsでECを作るときは、キャッシュの考え方が重要です。
キャッシュとは、一度取得したデータや生成したページを再利用して、表示を速くする仕組みです。
Next.js公式ドキュメントでは、サーバー側のfetchを拡張し、リクエストごとにキャッシュや再検証の設定をできると説明されています。(nextjs.org)
また、revalidatePathを使うと、指定したパスを再検証対象にできます。Route Handlerから呼ぶ場合は、指定したパスへの次回アクセス時に再検証されると説明されています。(nextjs.org)
ECでは、情報ごとに更新頻度が違います。
ほとんど変わらない
↓
ブランド紹介、FAQ、商品説明
たまに変わる
↓
商品価格、商品画像、カテゴリ
頻繁に変わる
↓
在庫、注文ステータス、決済状況
これらをすべて同じ扱いにすると、無駄が増えます。
商品説明のようにあまり変わらない情報はキャッシュできます。
一方、注文ステータスや決済状況は毎回確認する必要があります。
ECでの考え方
商品ページ
↓
キャッシュしやすい
商品一覧
↓
キャッシュしやすい
在庫表示
↓
必要に応じて動的
注文確認
↓
動的
管理画面
↓
動的
Webhook
↓
キャッシュしない
Route Handlersについても注意が必要です。
Next.js公式ドキュメントでは、Route Handlersはデフォルトではキャッシュされず、GETメソッドは設定によりキャッシュ可能、その他のHTTPメソッドはキャッシュされないと説明されています。(nextjs.org)
攻略ポイント
ECでは、何でもキャッシュしてはいけません。
キャッシュしてよいもの
↓
商品説明、画像、FAQ、記事
キャッシュしてはいけないもの
↓
決済状況、注文処理、Webhook、管理画面の重要更新
表示速度を上げることは大切です。
しかし、注文や決済の正しさを犠牲にしてはいけません。
3.8 画像最適化と商品一覧のパフォーマンス
ECサイトでは、画像がとても重要です。
商品画像がきれいで見やすいことは、購入判断に直結します。
しかし、画像が重すぎるとページ表示が遅くなります。
そのため、画像最適化が必要です。
Next.jsには、画像最適化のための機能があります。
Next.js公式ドキュメントでは、next/imageを使うことで、画像のサイズ最適化、レイアウトシフト防止、遅延読み込みなどに対応できると説明されています。(nextjs.org)
商品一覧ページでは、特に注意が必要です。
商品カードが20件、30件と並ぶと、画像の読み込み量が増えるからです。
商品一覧でやるべきこと
画像サイズを適切にする
next/imageを使う
一覧用の軽い画像を用意する
最初に表示される画像を優先する
不要なアニメーションを避ける
商品カードを軽くする
やってはいけないこと
巨大な画像をそのまま表示する
すべての画像を一気に読み込む
商品カードごとに重いClient Componentを使う
一覧ページに複雑な処理を詰め込む
商品一覧は、軽さが大切です。
ユーザーは、まず一覧で商品を探します。
そこで重くなると、詳細ページまで進んでもらえません。
攻略ポイント
商品一覧ページは、
画像を見せる場所であり、重い処理をする場所ではないと考えます。
一覧ページ
↓
軽く、速く、見やすく
詳細ページ
↓
説明を丁寧に、購入判断しやすく
この役割分担が大切です。
3.9 SEOとOGPを考慮した商品ページ設計
ECサイトでは、商品ページのSEOも重要です。
SEOとは、Googleなどの検索結果で見つけてもらいやすくするための設計です。
商品ページは、ただ商品を売るだけではありません。
検索からお客様を連れてくる入口にもなります。
Next.jsでは、Metadata APIを使って、ページごとのタイトルや説明文などを設定できます。公式ドキュメントでは、静的なmetadataオブジェクトや動的なgenerateMetadata関数を使ってメタデータを定義できると説明されています。(nextjs.org)
商品ページで設定したい情報は、次の通りです。
title
description
Open Graph title
Open Graph description
Open Graph image
canonical URL
構造化データ
商品ページのtitle
商品名だけではなく、検索される言葉を自然に含めます。
悪い例
↓
極上だし
よい例
↓
極上だし|毎日の味噌汁を変える本格だしパック
description
検索結果で表示される説明文です。
購入前の不安を減らす内容にします。
素材
味の特徴
使い方
おすすめの用途
ギフト対応
OGP
OGPは、SNSやLINEなどでページを共有したときに表示される情報です。
商品ページがシェアされたときに、魅力的な画像とタイトルが出るようにします。
攻略ポイント
商品ページは、
販売ページであり、検索入口であり、SNS共有ページでもあると考えます。
購入者向け
↓
商品の魅力を伝える
検索エンジン向け
↓
内容を正しく伝える
SNS向け
↓
見たくなる画像とタイトルを用意する
この3つを意識すると、商品ページの価値が上がります。
3.10 Vercelで運用する場合の基本構成
Next.jsを運用する場合、Vercelは非常に相性の良い選択肢です。
VercelはNext.jsを開発している企業が提供するホスティングサービスで、Next.jsアプリをデプロイしやすい構成になっています。
Vercel公式ドキュメントでは、Next.jsプロジェクトをVercelにデプロイすると、プレビュー環境や本番環境、ドメイン設定、環境変数管理などを利用できることが説明されています。(vercel.com)
ECでVercelを使う場合、基本構成は次のようになります。
GitHub
↓
Vercel
↓
Next.jsアプリ
↓
Square API
↓
Square決済ページ
環境変数
Square APIを使う場合、Access TokenやLocation IDを環境変数として保存します。
SQUARE_ACCESS_TOKEN
SQUARE_LOCATION_ID
SQUARE_ENVIRONMENT
SQUARE_WEBHOOK_SIGNATURE_KEY
NEXT_PUBLIC_APP_URL
ここで重要なのは、秘密情報にNEXT_PUBLIC_を付けないことです。
Next.jsでは、NEXT_PUBLIC_が付いた環境変数はブラウザ側にも公開されます。
そのため、Access Tokenのような秘密情報には絶対に付けてはいけません。
よい例
↓
SQUARE_ACCESS_TOKEN
悪い例
↓
NEXT_PUBLIC_SQUARE_ACCESS_TOKEN
本番環境とテスト環境
SquareにはSandbox環境があります。
開発中はSandboxを使い、本番公開時にProductionへ切り替えます。
開発中
↓
Square Sandbox
本番公開
↓
Square Production
Vercel側でも、Preview環境とProduction環境で環境変数を分けると安全です。
Webhook URL
SquareからWebhookを受け取るには、公開されたURLが必要です。
Vercelにデプロイすると、Next.jsのRoute Handlerで作ったWebhook受信用URLをSquare側に登録できます。
https://example.com/api/square/webhook
攻略ポイント
Vercel運用で特に重要なのは、環境変数とWebhook URLです。
Access Token
↓
サーバー側だけで使う
Webhook URL
↓
Squareに登録する
SandboxとProduction
↓
絶対に混ぜない
テスト環境と本番環境を混ぜると、注文や決済で大きな事故につながります。
最初から環境を分けて設計します。
この章のまとめ
Next.jsでECを作るときは、App Routerを前提に設計します。
画面、API、サーバー処理、外部連携を分けて考えると、構成がわかりやすくなります。
基本の役割分担は次の通りです。
Server Component
↓
商品ページ、商品一覧、SEOページ
Client Component
↓
カート操作、数量変更、フォーム入力
Route Handlers
↓
Square API連携、Webhook受信
Server Actions
↓
フォーム送信、注文作成、管理画面の更新
商品ページや商品一覧は、できるだけ高速に表示します。
一方で、決済、注文、Webhook、管理画面など、正確性が必要な処理はキャッシュせず、サーバー側で慎重に扱います。
EC開発では、速さと正確さのバランスが重要です。
速く見せるべきもの
↓
商品ページ、商品一覧、記事、FAQ
正確に処理すべきもの
↓
注文、決済、在庫、Webhook、管理画面
この考え方が、Next.jsでECを作る基本になります。
次の章でやること
次の章では、実際に開発環境を準備します。
Next.jsプロジェクトを作り、TypeScript、Tailwind CSS、環境変数、Square Sandbox、Vercel連携などを整えていきます。
ここから、いよいよ実装ステージに入ります。
まずは、最小構成のECを作るための土台を作りましょう。