VOOZH about

URL: https://next-auth.js.org/configuration/pages

⇱ Pages | NextAuth.js


Skip to main content
🎉 NextAuth.js is now part of Better Auth!
Version: v4

NextAuth.js automatically creates simple, unbranded authentication pages for handling Sign in, Sign out, Email Verification and displaying error messages.

The options displayed on the sign-up page are automatically generated based on the providers specified in the options passed to NextAuth.js.

To add a custom login page, you can use the pages option:

pages/api/auth/[...nextauth].js
...
pages:{
signIn:'/auth/signin',
signOut:'/auth/signout',
error:'/auth/error',// Error code passed in query string as ?error=
verifyRequest:'/auth/verify-request',// (used for check email message)
newUser:'/auth/new-user'// New users will be directed here on first sign in (leave the property out if not of interest)
}
...
note

When using this configuration, ensure that these pages actually exist. For example error: '/auth/error' refers to a page file at pages/auth/error.js.

Error codes

We purposefully restrict the returned error codes for increased security.

Error page

The following errors are passed as error query parameters to the default or overridden error page:

  • Configuration: There is a problem with the server configuration. Check if your options are correct.
  • AccessDenied: Usually occurs, when you restricted access through the signIn callback, or redirect callback
  • Verification: Related to the Email provider. The token has expired or has already been used
  • Default: Catch all, will apply, if none of the above matched

Example: /auth/error?error=Configuration

Sign-in page

The following errors are passed as error query parameters to the default or overridden sign-in page:

  • OAuthSignin: Error in constructing an authorization URL (1, 2, 3),
  • OAuthCallback: Error in handling the response (1, 2, 3) from an OAuth provider.
  • OAuthCreateAccount: Could not create OAuth provider user in the database.
  • EmailCreateAccount: Could not create email provider user in the database.
  • Callback: Error in the OAuth callback handler route
  • OAuthAccountNotLinked: If the email on the account is already linked, but not with this OAuth account
  • EmailSignin: Sending the e-mail with the verification token failed
  • CredentialsSignin: The authorize callback returned null in the Credentials provider. We don't recommend providing information about which part of the credentials were wrong, as it might be abused by malicious hackers.
  • SessionRequired: The content of this page requires you to be signed in at all times. See useSession for configuration.
  • Default: Catch all, will apply, if none of the above matched

Example: /auth/signin?error=Default

Theming

By default, the built-in pages will follow the system theme, utilizing the prefer-color-scheme Media Query. You can override this to always use a dark or light theme, through the theme.colorScheme option.

In addition, you can define a theme.brandColor to define a custom accent color for these built-in pages. You can also define a URL to a logo in theme.logo which will be rendered above the primary card in these pages.

Sign In

👁 Customized Signin Page

Sign Out

👁 Customized Signout Page

Examples

OAuth Sign in

In order to get the available authentication providers and the URLs to use for them, you can make a request to the API endpoint /api/auth/providers:

pages/auth/signin.tsx
importtype{
GetServerSidePropsContext,
InferGetServerSidePropsType,
}from"next"
import{ getProviders, signIn }from"next-auth/react"
import{ getServerSession }from"next-auth/next"
import{ authOptions }from"../api/auth/[...nextauth]"

exportdefaultfunctionSignIn({
providers,
}:InferGetServerSidePropsType<typeof getServerSideProps>){
return(
<>
{Object.values(providers).map((provider)=>(
<divkey={provider.name}>
<buttononClick={()=>signIn(provider.id)}>
Sign in with {provider.name}
</button>
</div>
))}
</>
)
}

exportasyncfunctiongetServerSideProps(context:GetServerSidePropsContext){
const session =awaitgetServerSession(context.req, context.res, authOptions)

// If the user is already logged in, redirect.
// Note: Make sure not to redirect to the same page
// To avoid an infinite loop!
if(session){
return{ redirect:{ destination:"/"}}
}

const providers =awaitgetProviders()

return{
props:{ providers: providers ??[]},
}
}

There is another, more fully styled example signin page available here.

Email Sign in

If you create a custom sign in form for email sign in, you will need to submit both fields for the email address and csrfToken from /api/auth/csrf in a POST request to /api/auth/signin/email.

pages/auth/email-signin.tsx
importtype{
GetServerSidePropsContext,
InferGetServerSidePropsType,
}from"next"
import{ getCsrfToken }from"next-auth/react"

exportdefaultfunctionSignIn({
csrfToken,
}:InferGetServerSidePropsType<typeof getServerSideProps>){
return(
<formmethod="post"action="/api/auth/signin/email">
<inputname="csrfToken"type="hidden"defaultValue={csrfToken}/>
<label>
Email address
<inputtype="email"id="email"name="email"/>
</label>
<buttontype="submit">Sign in with Email</button>
</form>
)
}

exportasyncfunctiongetServerSideProps(context:GetServerSidePropsContext){
const csrfToken =awaitgetCsrfToken(context)
return{
props:{ csrfToken },
}
}

You can also use the signIn() function which will handle obtaining the CSRF token for you:

signIn("email",{ email:"jsmith@example.com"})

Credentials Sign in

If you create a sign in form for credentials based authentication, you will need to pass a csrfToken from /api/auth/csrf in a POST request to /api/auth/callback/credentials.

pages/auth/credentials-signin.tsx
importtype{
GetServerSidePropsContext,
InferGetServerSidePropsType,
}from"next"
import{ getCsrfToken }from"next-auth/react"

exportdefaultfunctionSignIn({
csrfToken,
}:InferGetServerSidePropsType<typeof getServerSideProps>){
return(
<formmethod="post"action="/api/auth/callback/credentials">
<inputname="csrfToken"type="hidden"defaultValue={csrfToken}/>
<label>
Username
<inputname="username"type="text"/>
</label>
<label>
Password
<inputname="password"type="password"/>
</label>
<buttontype="submit">Sign in</button>
</form>
)
}

exportasyncfunctiongetServerSideProps(context:GetServerSidePropsContext){
return{
props:{
csrfToken:awaitgetCsrfToken(context),
},
}
}

You can also use the signIn() function which will handle obtaining the CSRF token for you:

signIn("credentials",{ username:"jsmith", password:"1234"})
tip

Remember to put any custom pages in a folder outside /pages/api which is reserved for API code. As per the examples above, a location convention suggestion is pages/auth/....