Next.js 13(App Router) + TypeScript + Vercel で、本番環境とステージング環境を作る
はじめに
Next.js 13(App Router)をVercelにデプロイして、本番環境と、Basic認証付きのステージング環境を作成する方法です。
環境
- node: 18以上
- next: 13.4.19
create-next-app
まずはcreate-next-app
npx create-next-app
TypeScript
とApp Router
を使用するので、下記の質問ではYes
を選択してください。
他はお好みで設定してください。
? Would you like to use TypeScript? … No / Yes
? Would you like to use App Router? (recommended) … No / Yes
Next.jsでプロジェクトを作成することができたら、リポジトリにて管理します。
Vercelにデプロイ
Vercelにログイン。
リポジトリ単位でVercelへimportすることができます。
Deploy
ボタンを押すと main
ブランチの内容が、デプロイされます(簡単!)
xxx-xxx.vercel.app
といったドメインが自動で割り当てられるので、main
ブランチの内容が表示されてたらOK!
ステージングの作成
Project Setting
→Domain
からドメインを作成します。
今回はステージング環境のドメインはpreview-xxx-xxx.vercel.app
としたいので、入力して Add
を押します。
ドメインが追加されたらEdit
から詳細設定を行います。
Git Branch
にpreview-xxx-xxx.vercel.app
と紐づけたいブランチ名を入力します。 (ここではpreview
)
これで、
main
ブランチでpushすると xxx-xxx.vercel.app
へ、
preview
ブランチでpushすると preview-xxx-xxx.vercel.app
へ
デプロイされる環境が作れることができました。
ステージング(preview)にBasic認証をかける
必要なファィルの作成
ステージング環境にBasic
認証をかけるため、2つのファイルを作成します。
app
にapi
というフォルダを作ってその中にauth.ts
というファイルを作ります。
import type { NextApiRequest, NextApiResponse } from "next";
export default function handler(_: NextApiRequest, res: NextApiResponse) {
res.setHeader("WWW-authenticate", 'Basic realm="Secure Area"');
res.statusCode = 401;
res.end(`Auth Required.`);
}
加えてapp
と同階層にmiddleware.ts
というファイルを作ります。
import { NextRequest, NextResponse } from 'next/server';
/**
* @see https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher
*/
export const config = {
matcher: ['/:path*', '/index/:path*'],
};
export function middleware(req: NextRequest) {
if (process.env.NEXT_PUBLIC_VERCEL_ENV === "preview") {
const basicAuth = req.headers.get('Authorization');
if (basicAuth) {
const authValue = basicAuth.split(' ')[1];
// atob is deprecated but Buffer.from is not available in Next.js edge.
const [user, password] = atob(authValue).split(':');
if (
user === process.env.BASIC_USERNAME &&
password === process.env.BASIC_PASSWORD
) {
return NextResponse.next();
}
return NextResponse.json(
{ error: 'Invalid credentials' },
{ headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' }, status: 401 }
);
} else {
return NextResponse.json(
{ error: 'Please enter credentials' },
{ headers: { 'WWW-Authenticate': 'Basic realm="Secure Area"' }, status: 401 }
);
}
}
}
全体のディレクトリ構成は下記のようになります。
src
├─ app
│ ├─ api
│ │ └─ auth.ts
│ ├─ layout.tsx
│ └─ page.tsx
└─ middleware.ts
Vercelで設定
Project Setting
→Environment Variables
こちらから環境変数を設定することができます。
まずKey
にBASIC_USERNAME
、 BASIC_PASSWORD
を入力し、それぞれのValue
を入力します。
これがBasic認証のアイパスになります。
そしてEnvironment
にてPreview
のみにチェックを入れます。
Save
を押して設定を保存。
preview-xxx-xxx.vercel.app
にアクセスして、Basic認証がかかっていればOKです。
Discussion