You are viewing the docs for v0.6. This is not the latest version.

Custom sign-in Page

Provider: authjs

To create a custom sign-in page you will need to:

  1. Create the custom sign-in page: Creating the actual page your user will enter their credentials on OR select their oauth provider (e.g., google, azure, ...)
  2. Configure the authjs-backend-auth-handler to redirect to the custom sign-in page: If a sign-in is triggered or a session check fails, the authjs-backend-auth-handler has to forward you to your custom sign-in page, instead of the the authjs-backend-auth-handler builtin sign-in page
  3. Optional: Disable the nuxt-auth global protection middleware for the custom page if you have it enabled

Create the Custom sign-in Page

To create your custom sign-in page you can use signIn to directly start a provider-flow once the user selected it, e.g., by clicking on a button on your custom sign-in page. Here is a very simple sign-in page that either directly starts a github-oauth sign-in flow or directly signs in the user via the credentials flow:

<!-- file: ~/pages/login.vue --><template>  <div>    <p>Sign-In Options:</p>    <button @click="signIn('github')">Github</button>    <!-- NOTE: Here we hard-coded username and password, on your own page this should probably be connected to two inputs for username + password -->    <button @click="signIn('credentials', { username: 'test', password: 'hunter2' })">Username and Password</button>  </div></template><script setup lang="ts">definePageMeta({    auth: {        unauthenticatedOnly: true,        navigateAuthenticatedTo: '/',    }})const { signIn } = useAuth()</script>

Note:

  • In the above example username and password are hard-coded. In your own custom page, these two fields should probably come from inputs on your page.
  • We disable the global nuxt-auth middleware for this page by using the guest mode definePageMeta({ auth: { unauthenticatedOnly: true, ... } }), this is only necessary if you have set globalAppMiddleware: true in the nuxt-auth module configuration

If you want to create a custom sign-in page that dynamically offers sign-in options based on your configured providers, you can call getProviders() first and then iterate over the supported providers to generate your sign-in page.

Above we use the guest mode. This option was introduced in [email protected]. If you are on a previous version, use auth: false instead. This has the downside of not automatically redirecting authenticated users away from the login page.

Configure authjs to redirect to the Custom sign-in Page

Redirects to the sign-in page happen automatically, e.g., when a getSession() call fails to get a session or when signIn() is called. By default this redirect sends the user to /api/auth/signin. To use a custom sign-in page we will have to configure authjs to send the user to the custom sign-in page instead.

We can apply this configuration in the NuxtAuthHandler:

// file: ~/server/api/auth/[...].tsimport { NuxtAuthHandler } from '#auth'export default NuxtAuthHandler({  pages: {    // Change the default behavior to use `/login` as the path for the sign-in page    signIn: '/login'  },  providers: [    // ... your provider configuration  ]})

We can also configure the default-location for other pages in the pages configuration, see the NextAuth.js pages docs for more.

Disable the global page protection middleware

As already outlined in the first step, you will need to add:

definePageMeta({    auth: {        unauthenticatedOnly: true,        navigateAuthenticatedTo: '/',    }})

to your login page if you have enabled the global page protection middleware. This is the guest mode and allows unauthenticated users to access the login-page, while authenticated users will be redirected to /. Not disabling the global middleware would result in an endless loop of redirects. You can change navigateAuthenticatedTo to any route you like, e.g., /profile to show authenticated users their profile instead.

If you have not set globalAppMiddleware or have set it to false this step does not apply to your application.

Above we use the guest mode. This option was introduced in [email protected]. If you are on a previous version, use auth: false instead. This has the downside of not automatically redirecting authenticated users away from the login page.

Optional: Custom Error handling

You can handle sign-in errors yourself by calling signIn with redirect: false and inspecting its result for errors. For example:

const { signIn } = useAuth()const mySignInHandler = async ({ username, password }: { username: string, password: string }) => {  const { error, url } = await signIn('credentials', { username, password, redirect: false })  if (error) {    // Do your custom error handling here    alert('You have made a terrible mistake while entering your credentials')  } else {    // No error, continue with the sign in, e.g., by following the returned redirect:    return navigateTo(url, { external: true })  }}

Then call the mySignInHandler({ username, password }) on login instead of the default signIn(...) method. You can find all possible errors here. This file also contains the default error-messages that nuxt-auth would show to the user if you would not handle the error manually using redirect: false.

Provider: local

The only way to use the local provider does not come with a pre-made login page, so you will have to build one yourself. To do so:

  1. Create the page, e.g., pages/login.vue
  2. Call the signIn method with the username and password your user has to enter on this page
  3. Disable the page protection, if you have the global middleware enabled
  4. Configure nuxt-auth to know the place of your login page

A full example login page could look like this:

<!-- file: ~/pages/my-cool-login.vue --><template>  <div>    <p>Sign-In:</p>    <!-- NOTE: Here we hard-coded username and password, on your own page this should probably be connected to two inputs for username + password -->    <button @click="signIn('credentials', { username: 'test', password: 'hunter2' })">Username and Password</button>  </div></template><script setup lang="ts">definePageMeta({    auth: {        unauthenticatedOnly: true,        navigateAuthenticatedTo: '/',    }})const { signIn } = useAuth()</script>

Then the full nuxt.config.ts for this would look like this:

export default defineNuxtConfig({  modules: ['@sidebase/nuxt-auth'],  auth: {    provider: {      type: 'local',      pages: {        login: '/my-cool-login'      },    },    globalAppMiddleware: {      isEnabled: true    }  }})

Note:

  • if your global app middleware is disabled, you have to add auth: true to the definePageMeta-code above to correctly enable the guest-mode
  • the default location set for the login page is /login