Next.jsでリダイレクトを行う方法をまとめてみた
この記事について
この記事は、Next.jsのリダイレクト処理をまとめた記事になります。
Next.jsの基本的な理解がある事を前提に解説してきますので、予めご了承ください。
想定する環境
"dependencies": {
"next": "10.2.0",
"react": "17.0.2",
"react-dom": "17.0.2"
},
getStaticProps・getServerSideProps を使う場合
サーバー側でリダイレクト処理を行いたい場合は、この方法が便利です。
サーバー側で実行されるので、Cookie を用いた処理や DB との連携が可能となっていますが、リダイレクトの処理はどうしても遅くなってしまう傾向にあるので、ユーザー体験を求めないページ(認証が必要なページなど)に使用する事をオススメします。
import { GetServerSideProps } from 'next'
export const getServerSideProps: GetServerSideProps = async () => {
return {
redirect: {
permanent: false, // 永続的なリダイレクトかどうか
destination: '/redirect_page_url', // リダイレクト先
// destination: 'https://example.com/' // 別サイトでも指定可能
},
// ステータスコードを変更する場合は、`permanent`の代わりに`statusCode`を使用します。
redirect: {
statusCode: 302, // ステータスコード指定
destination: '/redirect_page_url', // リダイレクト先
},
}
}
オプション
また、redirect
に設定できる値は以下の通りです。
export type Redirect =
| {
statusCode: 301 | 302 | 303 | 307 | 308; // ステータスコード
destination: string; // リダイレクト先のURL
basePath?: false; // `basePath`を無効にします
}
| {
permanent: boolean; // 永続的なリダイレクト化のフラグ
destination: string; // 同上
basePath?: false; // 同上
};
// basePathについては以下を参照してください👇
// https://nextjs.org/docs/api-reference/next.config.js/basepath
参照
詳しい挙動は、以下のファイルから確認できます 👇
getInitialProps を使う場合
サーバー・クライアント両方の環境でリダイレクト処理を行いたい時には、この方法が便利です。
実装は複雑になってしまいますが、他の方法よりも体験の良いリダイレクトを行えるため、ユーザー体験を求めるページなどで使用すると良いと思います。
import { NextPage } from 'next'
import Router from 'next/router'
const RedirectPage: NextPage = () => {/* -- 省略 -- */}
RedirectPage.getInitialProps = async ({ res }) => {
// サーバー側でリダイレクト
if (typeof window === 'undefined') {
res.writeHead(302, { Location: '/redirect_page_url' })
res.end()
return {} // 空オブジェクトだと警告文が発生するので注意してください!
}
// クライアント側でリダイレクト
Router.push('/redirect_page_url')
return {} // 同上
}
export default RedirectPage
useEffect を使う場合
SPAなどでリダイレクト処理をしたい場合や、Firebase Authなどのようなサービスと連携する必要がある場合は、この方法が使えます。
クライアント側でリダイレクト処理を行えるため、クライアントの状態を使ったリダイレクトが簡単に実装でき、比較的速いリダイレクトができます。
しかし、サーバー側との連携が必要な場合は少し工夫する必要があったり、useEffect()の仕様上、一度描画されてしまうので、ちょっと見栄えが悪くなる可能性があります。
import { NextPage } from 'next'
import { useRouter } from 'next/router'
const RedirectPage: NextPage = () => {
const router = useRouter()
useEffect(() => {
router.replace('/redirect_page_url') // ここでリダイレクト
}, [])
return null
}
実装例
より具体的な実装例は、以下の記事が参考になります 👇
設定ファイルを使ってリダイレクト
next.config.js
のredirects
を設定する事でもリダイレクト処理を実装できます。
この方法ではページコンポーネントを必要としないので、ページに左右されないリダイレクトを行いたい時に便利です ✨
/** @type {import('next/dist/next-server/server/config-shared').NextConfig} */
const config = {
async redirects() {
return [
{
source: '/about', // リダイレクト元のURL
destination: '/redirect_page_url', // リダイレクト先のURL
permanent: true, // 永続的なリダイレクトかのフラグ
},
]
},
}
module.exports = config
オプション
また、指定できるオプションは以下の通りです 👇
type Redirect = {
source: string; // リダイレクト元のパス文字列
destination: string; // リダイレクト先のパス文字列
basePath?: false; // `basePath`を無効にします
locale?: false; // localeをマッチング時に含めないかのフラグ
has?: RouteHas[]; // header, cookie, queryなどにマッチするための配列
statusCode?: number; // ステータスコード
permanent?: boolean; // 永続的なリダイレクトかのフラグ
};
// basePathについては以下を参照してください👇
// https://nextjs.org/docs/api-reference/next.config.js/basepath
// `has`オプションの型
export type RouteHas =
| {
type: "header" | "query" | "cookie";
key: string;
value?: string;
}
| {
type: "host";
key?: undefined;
value: string;
};
参考
結局、どれを使えばいいのか?
及ばせながら、筆者の知見をまとめると以下のようになります 👇
方法名 | 遷移時の体験の良さ | 実装のしやすさ | 自由度 |
---|---|---|---|
getServerSideProps | ❌ | ✅ | ✅ |
getStaticProps | ❌ | ✅ | ✅ |
useEffect | ❌ | ✅ | ❌ |
getInitialProps | ✅ | ❌ | ✅ |
設定ファイル | ✅ | ✅ | ❌ |
上記の表より、
ユーザー体験を求めない場合
getServerSideProps
getStaticProps
ユーザー体験を求める場合
getInitialProps
簡単に実装したい場合
useEffect
ページなどに関係なく処理したい場合
- 設定ファイル(
next.config.js
)
となります。
作るプロダクト、サーバーの状況、実装方法によって変わってくるとは思いますが、参考程度に思って頂ければ幸いです。
その他の参考リンク
あとがき
ここまで読んでくれてありがとうございます 🙏
記事に間違いなどがあれば、コメントなどで教えて頂けると嬉しいです。
これが誰かの参考になれば幸いです。
それではまた 👋
Discussion