4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NextjsのAppRouterで、redirect時に一度だけ表示する

Last updated at Posted at 2024-04-25

実装背景

Next.jsのAppRouterを使用してserver actionredirectを行うと、リダイレクト先のページで成功や失敗のメッセージを表示することが難しくなります。
これは、リダイレクトが発生すると、現在のページの状態がリセットされ、新しいページが読み込まれるためです。
これを解決するために、一度だけ表示するメッセージを保存する方法としてcookieを使用します。

サンプルリポジトリはこちら
https://github.com/yuyakinjo/next-app-flash

動作動画(aタグバージョン)

flash.gif

注意: /ページで表示されている、/flashページのリンクはaタグを使用しています

なぜaタグを使っているかは後述します。

流れ

  1. /ページ
  2. /formページで、入力
  3. 入力後、/flashページへリダイレクト
  4. flashという名前のcookieがあれば、successという文字を表示
  5. 一度、別のページに遷移したり、リロードすると文字が消える

ページ概要

  • /ページ: 各ページへリンクがあるページ
  • /formページ: フォームを入力し、formにはserver actionが設定されている。フォーム送信完了後はflashページへリダイレクト
  • /flashページ: flash表示ページ

cookiesを使う

cookiesは、nextjsが用意している関数で、maxAge(秒)0にすることで、リダイレクト後、一度だけ取得でき、すぐ消滅してくれるので削除する必要もありません。

Railsではflashと呼ばれています。

備考として、cookiesを使用すると、ページは毎回動的レンダリングになるはず。。。

あれ動的レンダリングされてなさそう

cookiesは動的関数で、それを使っているページは毎回動的レンダリングされ、キャッシュされないはずだけど、キャッシュされてるぞ!!!

スクリーンショット 2024-04-25 13.53.03.png

この表でいう、一番下じゃないのか。cookieもキャッシュされる対象になっているのかな。。。

もしかしたら、下記のドキュメントかもしれないけど、どこがそれに抵触する箇所なのか難しい
https://nextjs.org/docs/app/building-your-application/caching#full-route-cache

Linkコンポーネント使うと、cookieの値もキャッシュされて表示されちゃうよ

nextjsのlearnでもやるのですが、Linkコンポーネントはnextjsが用意してくれているprefetch(移動先のページをあらかじめ読み込んでくれてたり)をハンドリングできるコンポーネントなのですが、これが相性よくなかったみたいです。
aタグ使うと、毎回ページを読みに行きますのでやりたかった動きが叶いました。

Linkコンポーネントでも、cookie自体はブラウザからちゃんと消えてくれてます。

動作動画(Linkコンポーネントバージョン)

注意: /ページで表示されている、/flashページのリンクはLinkコンポーネントを使用しています

flash.gif

まとめ

リダイレクト後に、一度だけ表示したい(flash)は叶いましたが、flashを実装したページのリンク先には、aタグを使わないと、cookieの値もキャッシュされちゃうので気をつけてください。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?