はじめに
Next.jsのApp Routerはプロジェクトの構造をapp
ディレクトリ内でファイル名とフォルダ名とその組み合わせを元にして決定します。
この記事ではNext.jsのv15.1.0
から新たに追加された2つの予約されたファイル名と2つの機能を紹介します。
執筆現在v15.0.4-canary.33
でcanary
として存在しています。そのためこれから紹介する機能を利用するにはexperimental.authInterrupts
をtrue
に設定する必要があります。
const nextConfig: NextConfig = {
experimental: {
authInterrupts: true,
},
};
追加された機能を利用して作成したデモページを作成しました。実際に触りたい場合はこちらをどうぞ。
forbidden
forbidden.js
はnot-found.js
と同じような機能を持つファイルです。同時に追加されたforbidden
関数と合わせて権限の不足等のエラー時に利用されます。
ページのUIの作成中にfobidden
が呼び出された時、そのセグメントのpage.js
ではなく、403エラーと合わせてforbidden.js
に記述されたUIが表示されます(forbidden.js
がなければNext.jsが用意したデフォルトのUIが表示されます)。
import { forbidden } from 'next/navigation'
import { getUser } from '@/model/user'
export default async function CreateBlog() {
const user = await getUser()
// ブログを作成・編集する権限がなければforbiddenへ移動
if (!hasWriteBlogPermission(user.permissions)) {
// returnは不要
forbidden()
}
// 通常表示されるUI
return (
<main>
<CreateBlogForm />
</main>
)
}
forbidden
関数がサーバーアクション、ルートハンドラ内で実行された場合は、処理を中断してステータスコード403
を返します。
'use server'
import { forbidden, notFound } from 'next/navigation'
import { getUser } from '@/model/user'
import { getBlog, updateBlog } from '@/model/blog'
export async function update(formData: FormData) {
const user = await getUser()
const blog = await getBlog(formData)
// ブログがない場合は404を返す
if (!blog) {
notFound()
}
// ブログを記述したユーザーでない場合は403を返す
if (blog.userId !== user.id) {
forbidden()
}
// ブログの更新処理
// ...
}
unauthorized
unauthorized.js
もまたunauthorized
関数と合わせて未ログイン等のエラー時に利用されます。
ページのUIの作成中にunauthorized
が呼び出された時、そのセグメントのpage.js
ではなく、401エラーと合わせてunauthorized.js
に記述されたUIが表示されます(unauthorized.js
がなければNext.jsが用意したデフォルトのUIが表示されます)。
import { unauthorized } from 'next/navigation'
import { getUser } from '@/model/user'
export default async function CreateBlog() {
const user = await getUser()
// ログインしていない場合はunauthorizedへ移動
if (!user) {
// returnは不要
unauthorized()
}
// 通常表示されるUI
return (
<main>
<CreateBlogForm />
</main>
)
}
unauthorized
関数はサーバーアクション、ルートハンドラ内で実行された場合は、処理を中断してステータスコード401
を返します。
'use server'
import { unauthorized, forbidden, notFound } from 'next/navigation'
import { getUser } from '@/model/user'
import { getBlog, updateBlog } from '@/model/blog'
export async function update(formData: FormData) {
const user = await getUser()
// ログインしていない場合は401を返す
if (!user) {
unauthorized()
}
// ブログの更新処理
// ...
}
さいごに
Next.jsのcanary
で2つのFile Conventions
が追加され、それに関連する2つのnavigation
APIを紹介しました。
今後も新たな意味を持つファイル名が追加されると考えられるので、現存しないファイル名であっても_
を先頭につけるように心がけて行きたいです。