Authentication & Sessions
18 min read
Create the Registration Flow
Create the Registration Flow
Task
Connect the Register form to a server route that validates input, checks for an existing account, hashes the password, and creates the User record.
Route
Create:
app/api/auth/register/route.ts
Implementation
import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { registerSchema } from "@/lib/validation/auth";
import { hashPassword } from "@/lib/password";
export async function POST(request: Request) {
const parsed = registerSchema.safeParse(await request.json());
if (!parsed.success) {
return NextResponse.json(
{ error: "Invalid registration data" },
{ status: 400 },
);
}
const { name, email, password } = parsed.data;
const existing = await prisma.user.findUnique({
where: { email },
});
if (existing) {
return NextResponse.json(
{ error: "An account with that email already exists" },
{ status: 409 },
);
}
const passwordHash = await hashPassword(password);
const user = await prisma.user.create({
data: {
name,
email,
passwordHash,
},
select: {
id: true,
name: true,
email: true,
},
});
return NextResponse.json({ user }, { status: 201 });
}
Connect the Register form with fetch("/api/auth/register", { method: "POST", ... }) and display the returned error in the prepared UI.
Do not return passwordHash to the browser.
Test
Register a new account, then try the same email again.
Expected result:
- first request creates the account
- duplicate email returns
409 - invalid input returns
400 - the response never contains the password hash
Checkpoint
The Register screen creates real User records safely.