Build a custom register page with Next.js, Tailwind CSS, and Next-Auth
Build a custom registration page for NextAuth! The credential provider checks credentials against an external source, but there is nothing in NextAuth that helps get the user into the database in the first place.
This guide walks through creating the page and the API route to insert a new user into the database.
Technologies
It's okay if you have a slightly different technology stack. Just adapt the code and logic to your specific use case.
Guide
Follow along, or download the entire project.
Source: https://github.com/ethanmick/nextauth-custom-register
The first thing to do is to build the Register
page in the app directory:
The form is interactive, so it needs to be a client component. Create a new file in the same app/register
directory called form.tsx
that you can import:
'use client'
import { Alert } from '@/components/ui/alert'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { signIn } from 'next-auth/react'
import { useState } from 'react'
export const RegisterForm = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [error, setError] = useState<string | null>(null)
const onSubmit = async (e: React.FormEvent) => {
e.preventDefault()
try {
const res = await fetch('/api/register', {
method: 'POST',
body: JSON.stringify({
email,
password
}),
headers: {
'Content-Type': 'application/json'
}
})
if (res.ok) {
signIn()
} else {
setError((await res.json()).error)
}
} catch (error: any) {
setError(error?.message)
}
}
return (
<form onSubmit={onSubmit} className="space-y-12 w-full sm:w-[400px]">
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="email">Email</Label>
<Input
className="w-full"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
id="email"
type="email"
/>
</div>
<div className="grid w-full items-center gap-1.5">
<Label htmlFor="password">Password</Label>
<Input
className="w-full"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
id="password"
type="password"
/>
</div>
{error && <Alert>{error}</Alert>}
<div className="w-full">
<Button className="w-full" size="lg">
Register
</Button>
</div>
</form>
)
}
The components referenced can be copied and pulled in from here: https://ui.shadcn.com/docs/primitives/accordion
Last, to create the user in Prisma you need to create a new API route that will handle the incoming POST
request.
Create a new file: app/api/register/route.ts
and put in the following:
Always remember to be careful when dealing with user passwords. Here, we use Bcrypt to hash the password before saving it.
Source Code
You can find the source on my GitHub account: https://github.com/ethanmick/nextauth-custom-register