環境
- windows10
- DockerDesktop for Win 3.5.x
- Laravel 8.x
- PHP 8.x
- node 16.13.1
- npm 8.1.2
- TypeScript 4.5
- React 17.0.1
- Next.js 12.0.7
- Recoil 0.5.2
- VsCode
- gitbash 2.32.0.1
動作イメージ
- それぞれDocker上で起動しているfrontendコンテナからapi用のbackendコンテナにリクエストを送る(ホスト側からリクエストを送るわけではないので、ポートの指定に注意)
- 各コンテナのポートマッピングは以下の通り
- ホスト-frontend
- 8020: 3000
- ホスト-backend
- 9020: 8000
- ホスト-frontend
- CSRではuseEffectでhttpリクエストなどを送る際は、ホストから
- frontendコンテナではNext.jsが動いており、getServerSideProps()を使用してApiからデータを取得する
- Apiからのリソースの取得については、Axiosを使用する
- backendのApiはLaravelで作成しており、Cookieベースの認証を行う想定です
設定手順
AxiosのbaseUrlを修正
ブラウザから実行するのか、フロントエンドのサーバーから実行するのかでAxiosのbaseUrlを切り替える(frontendコンテナからだと、backendというサービス名で通信が可能となるため)
設定していないと、Error: connect ECONNREFUSEDとなる
import Axios from 'axios'
const axios = Axios.create({
// csrとssr時のリクエスト先が異なるため
baseURL: process.browser ? 'http://localhost:9020' : 'http://backend:8000',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
withCredentials: true
})
export default axios
Nodeサーバーからリクエストを投げる
- 対象のPages配下のディレクトリのコンポーネントでgetServerSidePropsを作成する
- 認証が必要なApiのルートにリクエストを投げる際は、ctx: GetServerSidePropsContextを引数で受けることにより、ブラウザからのリクエストに包含されているcookieを取得して、Apiへリクエストを投げる際に利用することが可能(これがないと401エラーになる)
- 上記のように、認証が必要なダッシュボードとかでもcookieを取得することは可能だが、そういったページはそもそもSEOを気にしなくてもよいので、SSRするはないという...(以下SWR公式より引用)
This approach works well for user dashboard pages, for example. Because a dashboard is a private, user-specific page, SEO is not relevant and the page doesn’t need to be pre-rendered. The data is frequently updated, which requires request-time data fetching.
- レスポンスはコンポーネントの引数で受けて、useEffect内等でそのまま使用することが可能
import axios from 'libs/axios'
import { GetServerSideProps } from 'next'
..
type POST = typeof postData
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const cookie = ctx.req?.headers.cookie
const res = await axios.get('/api/posts', {
headers: {
cookie: cookie!
}
})
const posts: POST[] = res.data
return {
props: {
posts: posts
}
}
}
const Home = ({ posts }) => {
..
以上です。上記の通り、認証が必要なルートへのリクエストをSSRで実装しようとすると少し面倒なので、基本は、CSRとしつつ、SEOに影響するページはSSRとする(もしくはSSGとする)というスタンスがベターなのではないかと思います。(そもそも公式もSSGが推奨としている...)
まとめ
いかがでしたでしょうか。本記事では、NextjsのSSR時にgetServerSidePropsで動的なデータを取得するための設定手順について紹介しています。認証が必要なルートへのリクエストをSSRで実装しようとすると少し面倒なので、基本は、CSRとしつつ、SEOに影響するページはSSRとする(もしくはSSGとする)というスタンスがベターなのではないかと思います