はじめに
お久しぶりです、株式会社 ONE WEDGEの@Shankouです。
今回はReact(Next.js)のStatic Exports設定で認証ロジックを作って行きたいと思います。
弊社ではサーバーレス開発を行っております。
ざっくりと説明するとバックエンドの処理をAWSのLambdaを使ってAPIとして実装し、フロントはAWSのS3にアップロードしたものをこれまたAWSのCloudFrontを使って配信するという形です。
案件ではVue(Nuxt.js)を使ってビルドした静的ファイルをS3にあげていますが、個人的にReactを勉強中なので、同じことをReactでどうやるの?ということをまとめてみたいと思います。
ちなみにStatic Exportsとはサーバーサイドロジックを含まず、フロントでのみ動作するようにビルドを行うモードのことです。(サーバーレス開発なので当然ですね)
そのうえで、認証ロジック、未認証ページと認証済みページの切り分け、更に認証済みページへのアクセス時に、未認証状態であれば自動でグインページに飛ばすというのをできるだけスマートにやりたいなということで、その辺りを手探りで実装しました。
今回使用しているNodeのバージョンは以下の通りです。
> node --version
v22.7.0
プロジェクトの作成
Next.jsのインストールをベースにプロジェクトを作成していきます。
各質問はプロジェクト名の入力以外は初期値のまま全部Enterキー押していくだけで大丈夫です。
ちなみにApp RouterというのはReactの新しいシステム構成方式になります。
> npx create-next-app@latest
Need to install the following packages:
create-next-app@14.2.7
# 続行してもいいですか? (y)
Ok to proceed? (y) y
# プロジェクト名を入力 (static-exports-sample)
? What is your project named? > static-exports-sample
# TypeScriptの利用を選択 (Yes)
? Would you like to use TypeScript? › No / Yes
# ESLintの利用を選択 (Yes)
? Would you like to use ESLint? › No / Yes
# Tailwind CSSの利用を選択 (Yes)
? Would you like to use Tailwind CSS? › No / Yes
# srcディレクトリ配下にソースファイルをまとめるかを選択 (Yes)
? Would you like to use `src/` directory? … No / Yes
# App Routerの利用を選択 (Yes)
? Would you like to use App Router? (recommended) › No / Yes
# デフォルトのインポートエイリアス記号を変更するか (No)
? Would you like to customize the default import alias (@/*)? › No / Yes
プロジェクトの作成が完了したらVScode等で開いてみてください。
Static Exportsの設定
続いてStatic Exportsの設定をしていきます。
プロジェクトディレクトリ直下にあるnext.config.js
を編集します。
const nextConfig = {
// Static Exportsの指定
output: 'export',
// 静的ファイルの生成先を指定
distDir: 'dist',
// 静的ファイルでの起動なので、サーバーサイドでの画像の最適化をOFF
images: {
unoptimized: true,
},
}
export default nextConfig
next.config.js
の設定ができたらビルドをおこなってみましょう。
> npm run build
プロジェクト直下にdistディレクトリが生成されていれば成功です。
dist
ディレクトリは.gitignore
に入れておくといいと思います。
サーバーレス開発では、このdistの中身をS3にアップロードしています。
ちょっとした注意点
環境変数(env)ファイルについて
環境変数を設定する際は、envファイルに記載する必要があるのですが、フロント側で使う環境変数にはNEXT_PUBLIC_
をプレフィックスとして付与する必要があります。
例えば以下の通りです。
NEXT_PUBLIC_API_BASE_URL="https://static-exports-sample.net/v1"
環境変数を使用する際は以下の様になります。
import axios from 'axios'
const instance = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
headers: {},
})
export default instance
use client
この辺りすごく面倒に感じているのですが、App RouterではデフォルトでServer Componentとして動作しようとするので、ブラウザ上でしか使用することができない変数・機能を使用するClient Componentでは、use client
宣言を1行目に入れる必要があります。
例えば以下の通りです。
'use client'
import { redirect } from 'next/navigation'
export default function Top() {
const redirectPath = '/home'
redirect(redirectPath)
}
上記コードではnext/navigation
がClient Componentでしか利用することができないため、use client
宣言が必須となります。
他にもuseState
等のイベントハンドラーが付与されるような機能もuse client
宣言が必須となっています。
use client
については公式ページに解説がありますが、正直Static Exportsなので全てのComponentに付与しておけばいいやと思っています。
Static Exports時の脳死付与について、何か副作用があるようでしたら教えてくださると助かります。
今回はここまで。
次回はライブラリ関連のインストールを行い、実装を進めていきます。
また、サーバーレスの認証ロジックの実装にはいろいろ注意点もあるので、その辺りのお話もしていこうと思います。