LoginSignup
8
4

App Router では NextAuth.js の authOptions は外部ファイルに切り出して export しよう

Posted at

結論

Next.js で App Router を利用している場合、 NextAuth.js の config である authOptions/api/auth/[...nextauth]/route.ts に直接記述するのではなく、外部ファイルへ切り出してからimportしましょう。

  • NG
/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth'
import type { NextAuthOptions } from 'next-auth'

export const authOptions: NextAuthOptions = {
  // your configs
}

export default NextAuth(authOptions);
  • OK
/lib/auth.ts
import type { NextAuthOptions } from "next-auth"

export const authOptions = {
  providers: [], // rest of your config
} satisfies NextAuthOptions

export const { handlers, auth, signIn, signOut } = NextAuth(authOptions)
/api/auth/[...nextauth]/route.ts
import { handler } from "@/lib/auth"
export { handler as GET, handler as POST }

理由

App Router の Route Handler では/api/.../route.ts内でexportできる関数が特定の HTTP Methods に限定されており、const authOptions: NextAuthOptions のようなオブジェクトをexportするとType errorとなるため。

Supported HTTP Methods
The following HTTP methods are supported: GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS. If an unsupported method is called, Next.js will return a 405 Method Not Allowed response.

実際にnext buildすると、以下のようなエラーが投げられます。

src/app/api/auth/[...nextauth]/route.ts
Type error: Route "src/app/api/auth/[...nextauth]/route.ts" does not match the required types of a Next.js Route.
  "authOptions" is not a valid Route export field.

関連情報

NextAuth.js 公式のサンプルでも同様の実装がなされています。

また、これまでauthOptions[...nextauth]/route.tsに記述していたのは単なる慣例である、と NextAuth.js のメインメンテナから言及もされています。

The place for authOptions in [...nextauth]/route.ts was just a convention. It came from before when the restriction for Next.js was introduced to only allow certain exports from Route Handler files.
authOptions[...nextauth]/route.tsに置くのは、単なる慣例でした。これは以前、Next.jsにRouteハンドラファイルからの特定のエクスポートのみを許可する制限が導入されたときに由来しています。DeepL による翻訳)

おまけのtips

同ファイル内でgetServerSession関数にauthOptionsを渡したヘルパー関数を定義してexportすれば各ファイルでauthOptionsimportする必要がなくなるよ、というtipsが公式から出されています。ご参考までに。

auth.ts
import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next"
import type { NextAuthOptions } from "next-auth"
import { getServerSession } from "next-auth"

// You'll need to import and pass this
// to `NextAuth` in `app/api/auth/[...nextauth]/route.ts`
export const config = {
  providers: [], // rest of your config
} satisfies NextAuthOptions

// Use it in server contexts
export function auth(...args: [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]] | [NextApiRequest, NextApiResponse] | []) {
  return getServerSession(...args, config)
}

参考

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4