Next.jsでcookieを扱うのは大変
Next.jsなどのサーバーサイドレンダリング(以下SSR)をしているフレームワークでcookieを扱うのは面倒くさいですよね。
その理由の一つとして、同じコードでもSSRの場合とクライアントでレンダリングしている場合で挙動が違うということがあります。
例をお見せしましょう
クライアントでレンダリングしている場合
console.log(document.cookie); // accessToken=test1234;
SSRの場合
console.log(document.cookie); // ReferenceError: document is not defined
原因
クライアントサイド(ブラウザ)でレンダリングしている時は、ブラウザに保存されているcookieにアクセスできるが,
SSRの時はブラウザに保存されているcookieにアクセスできません。
SSRの時にcookieを扱うには
SSRでcookieの情報はここに入っています
index.tsx
constTestPage:NextPage<Props>=(props)=>{return<div>test</div>
}TestPage.getInitialProps(ctx){// ここconsole.log(ctx.req.headers.cookie)// accessToken=test1234; return{};}
同じライブラリをクライアントとSSRで共有していたりすると、条件分岐などが大変ですね
そんな時に nookies を使います
https://www.npmjs.com/package/nookies
使い方
以下の例で示すようにクライアントサイドの場合ctxを渡さずに、SSRならctxを渡せば、cookieをオブジェクトに整形して返してくれます。
tool.ts
import{parseCookies}from'nookies';import{NextPageContext}from'next';exportfunctionprintCookie(ctx?:NextPageContext){constcookie=parseCookies(ctx);console.log(cookie)// { accessToken: 'test1234' }}
また、cookieの追加もクライアントとSSR分け隔てなく行ってくれます
set_cookie.ts
import{setCookie,destoroyCookie}from'nookies';import{NextPageContext}from'next';exportfunctionsetCookie(ctx?:NextPageContext,token:string){setCookie(ctx,'accessToken',token,{maxAge:30*24*60*60,});}// ついでにcookie削除(動作確認してません)exportfunctiondestoroyCookie(ctx?:NextPageContext){destroyCookie(ctx,'accesstToken')}
ライブラリを読んでみた(箇条書きです!)
https://github.com/maticzav/nookies
nookies/src/index.ts
constisBrowser=()=>typeofwindow!=='undefined'// 今の環境がSSRかクライアントサイドレンダリングか調べてるらしいです..if(ctx&&ctx.req&&ctx.req.headers&&ctx.req.headers.cookie){returncookie.parse(ctx.req.headers.cookieasstring,options)// SSRだったらctx.req.headers.cookieに入っているcookieをparseして返却}..if(isBrowser()){returncookie.parse(document.cookie,options)//クライアントだったらdocument.cookieにあるcookieをparseして返却}..ctx.res.setHeader('Set-Cookie',cookiesToSet)// SSRならレスポンスヘッダーにcookieをセットする..if(isBrowser()){|document.cookie=cookie.serialize(name,value,options)// クライアントならクッキーをセット}
まとめ
以上です。いかがでしたでしょうか?
参考になりましたら幸いです。