
【Next.js】GCSやS3でNext.jsを静的ホスティングする際の注意点(dynamic routing)
2021/10/30
Next.jsを静的ホスティングする際に、若干詰まったので注意点をまとめておきます(特にdynamic routingを使用する場合は注意)。
Next.jsはもともとSSR用のフレームワークだったこともあり、ホスティングには(Vercelなどのサービスを使用することを除けば)基本的にサーバーを用意してあげることが多いと思います。
一方でフロントエンドをホスティングするためにわざわざサーバーとかを用意したくはないので、S3やGCSでもホスティングしたい、という方も多いのではないでしょうか。
もちろん、Next.jsにはSSG機能が追加されたので静的ホスティングはできるようになっています。 ただし冒頭で述べたように、Vercelなどのサービスを使用する場合と比べて、いくつか注意しなければならない点も存在します。 Next.jsで静的ホスティングを行う際の参考になれば幸いです。
尚、S3やGCSでサイトをホスティングする方法はたくさんのサイトで紹介されているので、ここでは説明を省かせていただきます。
next build && next exportで静的ファイル出力
サーバー上でホスティングする場合はnext build && next startでOKですが、静的ホスティングする場合にはnext build && next exportを使用します。
next exportはビルドしたファイルを静的にホスティングできる形式で出力してくれるコマンドです。
基本的にはnext build && next exportで出力されたファイル群をS3やGCSにアップロードすれば、静的ホスティングはできるようになっています。
trailing slashの設定
デフォルトのnext build && next exportでは/pages/about/index.tsxや/pages/about.tsxのファイルは/about.htmlとして出力されます。
したがって、これらを静的ホスティングした際のurlはhttps://hostname/about.htmlとなるのですが、それが嫌な方はnext.config.jsに以下の設定を追加してあげるとOKです。
module.exports = {
trailingSlash: true,
}next build && next exportが/about/index.htmlという形式でファイルを出力してくれるようになるので、https://hostname/loginというurlでページへアクセスできます。
dynamic routingを使用したい場合
client側でページ生成を行うdynamic routingをNext.jsで使用する場合、S3やGCSにはそのページに該当するファイルが存在しないことに注意しなければなりません。
ファイルが存在しないため、直接そのページをリクエストすると404エラーのページが表示されてしまいます(Next.jsの内部リンクでルーティングする場合には問題ない)。
dynamic routingを使用する場合は、404ページ上で正しいページへリダイレクトするように処理をしてあげましょう。
↓のコードは、urlが/posts/[postId]に一致する場合に、Next.jsのRouterでリダイレクト処理を行う404ページの例です。
import React, { useEffect, useState } from 'react'
import Router from 'next/router'
const redirectPath = /^\/posts\/.+/g
const Custom404: React.FC = () => {
const [isNotFound, setIsNotFound] = useState(false)
useEffect(() => {
// Your condition that can validate the URL
const pathName = window.location.pathname
if (pathName.match(redirectPath)) {
Router.replace(pathName) // Redirect to the right page...
} else {
setIsNotFound(true)
}
}, [])
if (isNotFound) return <h1>404 - Page Not Found</h1>
return null
}
export default Custom404おわり
静的ホスティングだとCDNも気軽に使えて便利なのでおすすめ 👍
