🚅

Next.jsにおけるリダイレクトまとめ

2023/01/17に公開約2,600字

概要

Next.jsを使用したリダイレクト処理はいくらかの方法があります。
それぞれ特性を述べながら説明できればと思います。

環境

"next": "^13.1.1"
"react": "^18.2.0"

useEffectを利用する

React.useEffectを使用する方法です。

このフックを使うことで、レンダー後に何かの処理をしないといけない、ということを React > に伝えます。React はあなたが渡した関数を覚えており(これを「副作用(関数)」と呼ぶこと> とします)、DOM の更新の後にそれを呼び出します。この副作用の場合はドキュメントのタイト> ルをセットしていますが、データを取得したりその他何らかの命令型の API を呼び出したりす> ることも可能です。
https://ja.reactjs.org/docs/hooks-effect.html

公式にもある通り、useEffectはレンダー後に作用するフックです。
実装自体の難易度は比較的簡単と言えます。

_app.tsx
import React from 'react'
import { useRouter } from 'next/router'

function MyApp({ Component, pageProps, router }: AppProps) {
  const router = useRouter()

  React.useEffect(() => {
    if (router.asPath === '/xxx') {
      router.push('/ooo')
    }
  }, [router.asPath])

  return <Component {...pageProps} />
}

getInitialProps

getInitialPropsはサーバー上で動作します。
クライアント側のレンダリングがなされる前にリダイレクトすることが可能です。
https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/data-fetching/get-initial-props

_app.tsx
import App, { AppProps, AppContext } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

MyApp.getInitialProps = async (appContext: AppContext) => {
  const appProps = await App.getInitialProps(appContext)
  const {
    ctx,
    router: { asPath },
  } = appContext
  if (asPath === '/xxx') {
    ctx.res?.writeHead(302, {
      Location: '/ooo',
    })
    ctx.res?.end()
    return
  }
  return { ...appProps }
}

getServerSideProps

SSRを利用した方法です。
redirectオブジェクトを使用してリダイレクト可能です。

https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/data-fetching/get-server-side-props#redirect

export async function getServerSideProps(context) {
  const res = await fetch('xxx')
  const data = await res.json()

  if (!data) {
    return {
      redirect: {
        destination: '/',
        permanent: false,
      },
    }
  }

  return {
    props: {},
  }
}

middlewareを利用する

Next.js v12からmiddleware機能が導入されました。
middlewareに書いた処理はリクエストが完了する前に実行が可能です。

middleware.ts
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'

export function middleware(req: NextRequest) {
  return NextResponse.redirect(new URL('ooo', req.url))
}

export const config = {
  matcher: 'xxx',
}

matcherを指定することで、該当したパスをリダイレクトするようにできます。

最後に

それぞれ使用感が異なるので、環境に合わせて使用できればと思います。

Discussion

ログインするとコメントできます