うまく動かないとき
よくつまずく症状と、その原因、直し方をまとめています。
このページの内容
Server Actionの送信が403になる
原因
ハンドラは、Originヘッダーのホストが、答えているURLのホストと一致するPOSTだけを受け付けます。前に置いたプロキシがHostを書き換えていると、この2つが一致しなくなります。
直し方
プロキシで、元のHostをそのまま渡します。ハンドラを自分で呼ぶホストなら、訪問者が求めたURLでRequestを作ります。
redirect()を呼んでも別のページへ移らない
原因
redirect()は例外を投げて終わります。tryの中で呼ぶと、catchがその例外を受け取ってしまいます。
直し方
redirect()はtryの外で呼びます。
… belongs to what answers the request, and a page is a renderというエラーが出る
原因
ページの描画の中で、cookies()やresponseHeaders()、requestHeaders()を呼んでいます。ページは応答を書けません。
直し方
リクエストのヘッダーやCookieを読むなら、ページが受け取るrequestを使います。書くなら、guard.tsかServer Actionに移します。
ページがinternal errorとだけ表示される
原因
ハンドラが答えを作れず、serve()が500で答えています。上にSuspenseの境界が無い場所でServer Componentが例外を投げると、こうなります。
直し方
投げられた内容は、サーバーのログにk8ordo: GET /products/1 failedのような行で出ています。例外を訪問者に伝える表示が要るなら、error.tsxを置きます。
素のHTTPで配信すると、Cookieが保存されない
原因
cookies().set()のsecureは、既定でtrueです。ブラウザは、素のHTTPで届いたSecureのCookieを保存しません。既定がfalseになるのは、localhost、127.0.0.1、[::1]に素のHTTPで届いたリクエストだけです。
直し方
本番はHTTPSで配信します。それ以外の場所を素のHTTPで動かすなら、setにsecure: falseを渡します。
a cookie with sameSite "none" has to be secureというエラーが出る
原因
sameSite: 'none'のCookieにsecure: falseを渡しています。ブラウザはSecureの無いSameSite=Noneを捨てるので、黙って消える代わりに書いたところでエラーにしています。
直し方
sameSite: 'none'のCookieはsecureのままにして、HTTPSで配信します。
hydrationに失敗したというエラーが、本番でだけ出る
原因
ルートレイアウトが描いた文書は、まるごとhydrationの対象です。CDNの中には、HTMLを書き換える機能を持つものがあります。Webフォントの埋め込みやメールアドレスの難読化、スクリプトの遅延読み込みなどを有効にしていると、Reactが受け取る木とHTMLが食い違います。
直し方
CDNのその機能を切ります。フォントやスクリプトは別のoriginからリンクせず、同じoriginから配信すると、書き換えられるものが無くなります。
href()のパスやページのparamsに型が付かない
原因
tsconfig.jsonのincludeが.k8ordo/を読んでいません。.k8ordoはドットで始まるので、".k8ordo"のようにディレクトリ名だけを書いたincludeは、このディレクトリを読み飛ばします。
直し方
includeに.k8ordo/**/*.tsのようにグロブで書きます。
cloneした直後だけ、paramsが文字列の型になる
原因
.k8ordo/は生成物でgitに入らないので、cloneした直後にはまだありません。ルート表が無いと、PagePropsのparamsはスキーマの出力ではなく、文字列として型が付きます。
直し方
tscの前に一度vite devかvite buildを動かして、.k8ordo/を書かせます。
routes/ holds only page.tsx, …でビルドが止まる
原因
routes/の中に、ルートのファイル名ではないファイルがあります。拡張子だけが違うpage.tsも同じです。
直し方
部品やデータは、_parts/のように_で始まるディレクトリへ移します。ページなら拡張子を.tsxにします。
a params schema must validate synchronouslyというエラーが出る
原因
paramsSchemaが非同期に検証しています。どのルートがURLに答えるかは描画の前に決めるので、スキーマの結果を待てません。
直し方
スキーマには値の形の検証だけを書きます。データがあるかどうかはページで確かめ、無ければnotFound()を投げます。
'server-only' cannot be imported in client buildでビルドが止まる
原因
server-onlyをimportしたモジュールが、クライアントコンポーネントから読まれています。エラーの2行目から下が、そこに至ったimportの連鎖です。
直し方
クライアントコンポーネントからは直接読まず、Server Componentで読んだ値をpropsで渡します。
Functions cannot be passed directly to Client Componentsというエラーが出る
原因
Server Componentからクライアントコンポーネントへ、関数をpropsとして渡しています。propsはシリアライズして運ぶので、関数は渡せません。
直し方
関数を呼んだ結果の値を渡すか、関数をクライアントコンポーネントの側へ移します。
useRoute must render inside a matched <Router>というエラーが出る
原因
フレームワークの下では、ブラウザはルート表を持ちません。ページの木はサーバーから届くからです。そのためuseRoute()とuseParams()には、読むルートがありません。
直し方
ページが受け取ったparamsを、propsでクライアントコンポーネントに渡します。今のURLはusePathname()で読みます。