0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsでRSC Payloadがブラウザに表示される問題と対処法

Posted at

本記事ではProduction環境で不具合を出したお焚き上げ記事です。

みなさんは私の屍を超えてStgまでで対応する / Productionに出してしまったら速攻で対応しましょう。

redirect function in Next.js

Webの世界では当たり前に使われるリダイレクトですがもちろんNext.jsでも利用可能です。

Next.jsでリダイレクトを実装したい時にはredirectを使うことで実現できます。

import { redirect } from 'next/navigation'

export function Redirect() {
  redirect('/somewhere')
}

redirectの第一引数にpathをパスしてあげる。とても簡単ですね。

このとき 'use client' を明示していない場合はServer Sideで実行されます。

RSC

Next.jsのページはコンポーネントから生成されます。ref: Server and Client Component

詳細は省略しますがざっくり効率的にWebページをレンダリングするためにデータをチャンク化してclientに渡す仕組みと考えていただいて差し支えありません。

CDN

Next.jsから少し離れますが、静的なWebページやJS, CSS, 画像ファイルは毎回オリジンサーバーに取得するとネットワークのデータ転送の遅延やオリジンサーバーの負荷が上がります。

このときにはCDNを使ってエッジサーバーでデータを返すようにすると改善されます。

AWSで言うところのCloudFrontですね。

特定のpathに対してキャッシュをもたせることで都度オリジンサーバーへのアクセスをしなくて済むようになります。

不具合

この状況でredirectをするページをデプロイしたところHTMLが返ってくるはずのURLから何やら見慣れない文字列が返ってくるときがありました。
(毎回じゃなかったのが辛かったところ)

1:$Sreact.fragment
2:....
...

調査中に知りましたがこれはRSC Payloadが表示されている状態です。

原因

RSC payloadは効率的にWebサイトをレンダリングする仕組みですが、そのためにリクエストのクエリに ?_rsc=xxx のような文字列が含まれるときがあります。

参考にしたのは以下のissueです。

CDNのキャッシュ時にこの_rscを含むようにしてしまうとRSC PayloadがキャッシュされてHTMLがブラウザで表示できなくなる可能性があります。

まとめると:

  1. Server ComponentでRedirectを実行
  2. クライアントが?_rsc=xxxパラメータ付きでリクエスト
  3. CDNがこのパラメータを含めてキャッシュ
  4. 次回以降、通常のHTMLリクエストに対してRSC Payloadが返される

という流れになります。

対処

我々の場合は、本来不要なタイミングでredirectを実行していたことが原因でした

そのため本来であればredirectを含めずに実装を進めるべきでした。

またredirectが必要ある場合はCDN側で_rscを含めないようにする設定が必要です。

Terraformを使っている場合は以下のように設定すると解決できます。

resource "aws_cloudfront_cache_policy" "nextjs_policy" {
  name        = "sample name"
  comment     = "Cache policy for Next.js that excludes RSC parameters"
  default_ttl = 3600
  max_ttl     = 86400
  min_ttl     = 0

  parameters_in_cache_key_and_forwarded_to_origin {
    enable_accept_encoding_brotli = true
    enable_accept_encoding_gzip   = true

    query_strings_config {
      query_string_behavior = "allExcept"
      query_strings {
        items = ["_rsc"]
      }
    }
  }

  headers_config {
    header_behavior = "none"
  }

  cookies_config {
    cookie_behavior = "none"
  }
}
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?