🚚
Next.js で SSR/SSG したページに Cache-Control などのヘッダを設定する
Next.js には強力な Incremental Static Regeneration がありますが、Vercel 以外にホストしている場合は使うことができません。そのとき、Cache-Control
や Surrogate-Control
ヘッダを用いて Fastly のような CDN にキャッシュを持たせたくなります。
このヘッダの持たせ方に少しクセがあったので備忘録的に書きます。
例えば、/articles/[id]
にヘッダを持たせたいとします。
next.config.js
で設定
方法1. next.config.js
の headers で設定する方法です。
next.config.js
const cacheHeaders = [
{
key: 'Cache-Control',
value: 'max-age=0',
},
{
key: 'Surrogate-Control',
value: 'public, max-age=300',
},
];
module.exports = {
{
source: '/articles/:id*',
headers: cacheHeaders,
},
{
// Client Routing で SSR するページに遷移したとき
source: '/_next/data/:hash/articles/:id*',
headers: cacheHeaders,
},
};
Next.js における SSR は HTML と json の2パターンがあり、直接 SSR ページを開いた場合はレンダリング結果の HTML、他のページから next/link
や next/router
で遷移した場合は props が json として返されます。
単純に /articles/:id*
と指定するだけでは、HTML にしかヘッダが設定されません。json は /_next/data/${hash}/articles/search/${id}.json?id=${id}
のような path で配信されるため、/_next/data/:hash/articles/:id*
と指定します。
getServerSideProps
で設定
方法2. これは SSR 限定の方法ですが、getServerSideProps
でレスポンスを書き換える方法もあります。
/pages/articles/[id].tsx
export const getServerSideProps: GetServerSideProps<Props> = async (context) => {
context.res.setHeader('Cache-Control', 'max-age=0');
context.res.setHeader('Surrogate-Control', 'public, max-age=300');
return {
props: { ... },
};
};
GetServerSidePropsContext
が持つ res
オブジェクトに対する操作は、HTML と json の両方に反映されます。
おわりに
SSR 以外の場合にもっとシンプルに設定する方法がある気がしていて、もしあればおしえてください。
Discussion