はじめに
cookieにセットされたトークンを用いるため、axios
のオプションにwithCredentials
を追加しましたが、APIを叩いても401エラーとなり弾かれてました。自分の理解の浅さ故、何日も溶かしてしまったので、初学者の備忘録として残します。
結論
Next.jsでは、Server Componentsの使用をデフォルトとしているため、クライアント側にセットされたcookieをサーバーサイドで読み取ることができません。なので、一度cookieから吸い上げて、headerオプションにセットする必要がありました。
export async function getServerSideProps(context) {
const apidata = await getApi(context.req.cookies);
return { props: { api: apidata } };
}
import axios from 'axios';
export default async function getApi(cookies) {
const access_token = cookies['access_token'];
return await axios
.get('http://nginx-back:80/api', {
headers: {
'Content-Type': 'application/json;',
// withCredentials: true, ←これではダメ
Authorization: `JWT ${access_token}`,
},
})
.then((res) => {
const data = res.data as Data[];
return data;
})
.catch((e) => console.log(`エラーが発生しました: ${e}`));
}
Server Components、Client Componentsとは何か?
その名の通りですが、Server Componentsは、サーバー側でレンダリングされるコンポーネント。Client Componentsは、クライアント側でレンダリングされるコンポーネントです。
サーバーサイド・クライアントサイドにレンダリングを分けることによって、「従来のサーバーレンダリングのパフォーマンス向上」と「クライアントサイドのリッチな双方向性」を両立させながら、サーバー・クライアント両方の環境でアプリケーションを構築できるようになりました。
app
ディレクトリ内のコンポーネントは、デフォルトでServer Componentsとなり、Client Componentsとして扱うためには、コードの先頭(import文よりも上)に'use client'
とつける必要があります。
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
Sever Componentsのメリット
以下、公式からの引用です。
- データ取得
データの取得をデータソースに近いサーバーに移すことができます。これにより、レンダリングに必要なデータを取得する時間が短縮され、クライアントが行うべきリクエストの回数が減るため、パフォーマンスが向上します。
- セキュリティ
トークンやAPIキーなどの機密データやロジックを、クライアントに公開するリスクなしにサーバー上に保持できます。
- キャッシュ
サーバー上でレンダリングすることで、結果をキャッシュし、後続のリクエストやユーザー間で再利用することができます。これにより、各リクエストで実行されるレンダリングとデータ取得の量を減らすことで、パフォーマンスを向上させ、コストを削減することができます。
- バンドルサイズ
以前はクライアントJavaScriptのバンドルサイズに影響を及ぼしていた大きな依存関係をサーバーに残すことができます。クライアントがServer Componentの JavaScript をダウンロード、解析、実行する必要がないため、インターネットの速度が遅いユーザーや性能の低いデバイスを使用しているユーザーにとって有益です。
- 初期ページロードとファースト・コンテントフル・ペイント(FCP)
サーバー上で、ページのレンダリングに必要なJavaScriptをクライアントがダウンロード、解析、実行するのを待たずに、ユーザーがすぐにページを表示できるようにHTMLを生成することができます。
- 検索エンジン最適化とソーシャルネットワークの共有性
レンダリングされたHTMLは、検索エンジンのボットがページをインデックスしたり、ソーシャルネットワークのボットがページのソーシャルカードプレビューを生成するために使用することができます。
- ストリーミング
レンダリング作業を分割して、準備ができ次第クライアントにストリーミングできます。これにより、ユーザーはページ全体がサーバーでレンダリングされるのを待つことなく、ページの一部を早めに見ることができます。
おわりに
公式リファレンスをちゃんと読むって大事ですね。参照する癖をつけておけば、何日もネットを彷徨うこともなかったと思います。