Next.js 12にしました
公開 ( 更新) 履歴 (6)
ファイル構造を修正してたらNext.js 12が出たので導入しました。更新自体はnpm
i
next@latest
だけで問題なく動作しました。以下は追加でやったことの記録です。
next.config.mjsにする #link
ES Modulesで書けるようになったとのことでnext.config.jsをnext.config.mjsにしました。importのところを変えただけでwebpackのLoaderは相変わらずrequire
されちゃうので.cjsのままです。
middlewareを使う #link
単純なAPIであればmiddlewareで返せそうだったのでサイトマップとフィードを返すところでやってみました。
これまでの実装 #link
要件は次の通りでした。
サイトマップは
/sitemap.xml
で提供するフィードは
/feed.atom
で提供する
これはpublicにファイルを置けば簡単なのですが、content-typeには; charset=utf-8
をつけたいので以下のようにしました。
/api/sitemap
でサイトマップを返し/sitemap.xml
のrewriteをここに向ける/api/feed
フィードを返し/feed.atom
のrewriteをここに向ける
当時の実装:/next.config.js, /pages/api
middlewareの実装 #link
content-typeのわがままは要件であるとします。/pages/api
とrewriteを使うのは迂回をしている感じで具合が悪かったのでここをmiddlewareで解消することにしました。
import {NextResponse} from 'next/server';
import type {NextRequest} from 'next/server';
export const middleware = (req: NextRequest) => {
const {pathname} = req.nextUrl;
switch (pathname) {
case '/sitemap.xml':
return respondSitemap();
case '/feed.atom':
return respondFeed();
default:
return undefined;
}
};
const respondSitemap = () => new NextResponse(
[...serializeSitemap()].join('\n'),
{
headers: {
'content-type': 'application/xml; charset=utf-8',
'cache-control': 'public, max-age=3600',
},
},
);
const respondFeed = () => new NextResponse(
[...serializeFeed()].join('\n'),
{
headers: {
'content-type': 'application/atom+xml; charset=utf-8',
'cache-control': 'public, max-age=3600',
},
},
);
これで/pages/api
とrewriteの設定は不要になりました。
コンテンツが静的なのでmiddlewareを活用している感じは薄いですが、例えばJWTの検証を挟むにはちょうどいいですね。