Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/lychee.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
--exclude 'http://localhost.*'
--exclude 'https://localhost.*'
--exclude 'https://cockroachlabs.com'
--exclude 'https://www.gnu.org'
--exclude '^/.*'
'./**/*.md' './**/*.mdx'
workingDirectory: "content"
Expand All @@ -60,6 +61,7 @@ jobs:
--exclude 'http://localhost.*'
--exclude 'https://localhost.*'
--exclude 'https://cockroachlabs.com'
--exclude 'https://www.gnu.org'
--exclude '^/.*'
'./**/*.md' './**/*.mdx'
workingDirectory: "content"
Expand Down Expand Up @@ -97,7 +99,7 @@ jobs:
fi

- name: 📝 Comment Broken Links
if: ${{ always() && github.event.pull_request.head.repo.fork == false }}
if: ${{ always() && github.event.pull_request.head.repo.fork == false && (steps.lychee.outputs.exit_code != 0 || (steps.lychee-retry.conclusion != 'skipped' && steps.lychee-retry.outputs.exit_code != 0)) }}
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{ github.event.pull_request.number }}
Expand Down
78 changes: 41 additions & 37 deletions content/800-guides/230-betterauth-nextjs.mdx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
title: 'How to use Prisma ORM with Better-Auth and Next.js'
metaTitle: 'How to use Prisma ORM and Prisma Postgres with Better-Auth and Next.js'
description: 'Learn how to use Prisma ORM in a Next.js app with Better-Auth'
sidebar_label: 'Better-Auth (with Next.js)'
title: 'How to use Prisma ORM with Better Auth and Next.js'
metaTitle: 'How to use Prisma ORM and Prisma Postgres with Better Auth and Next.js'
description: 'Learn how to use Prisma ORM in a Next.js app with Better Auth'
sidebar_label: 'Better Auth (with Next.js)'
image: '/img/guides/prisma-betterauth-nextjs-cover.png'
completion_time: '25 min'
community_section: true
---

## Introduction

[Better-Auth](https://better-auth.com/) is a modern, open-source authentication solution for web applications. It's built with TypeScript, React, and Prisma to provide a simple and extensible auth experience.
[Better Auth](https://better-auth.com/) is a modern, open-source authentication solution for web applications. It's built with TypeScript and provides a simple and extensible auth experience with support for multiple database adapters, including Prisma.

In this guide, you'll wire Better-Auth into a brand-new [Next.js](https://nextjs.org/) app and persist users in a [Prisma Postgres](https://prisma.io/postgres) database. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/betterauth-nextjs).
In this guide, you'll wire Better Auth into a brand-new [Next.js](https://nextjs.org/) app and persist users in a [Prisma Postgres](https://prisma.io/postgres) database. You can find a complete example of this guide on [GitHub](https://github.com/prisma/prisma-examples/tree/latest/orm/betterauth-nextjs).

## Prerequisites

Expand Down Expand Up @@ -78,15 +78,15 @@ Once installed, initialize Prisma in your project:
npx prisma init --db --output ../src/generated/prisma
```
:::info
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Better-Auth Project"
You'll need to answer a few questions while setting up your Prisma Postgres database. Select the region closest to your location and a memorable name for your database like "My Better Auth Project"
:::

This will create:

- A `prisma` directory with a `schema.prisma` file.
- A Prisma Postgres database.
- A `.env` file containing the `DATABASE_URL` at the project root.
- An `output` directory for the generated Prisma Client as `better-auth/generated/prisma`.
- A `prisma` directory with a `schema.prisma` file
- A Prisma Postgres database
- A `.env` file containing the `DATABASE_URL` at the project root
- An `output` directory for the generated Prisma Client as `better-auth/generated/prisma`

### 2.2. Configure the Prisma client generator

Expand All @@ -98,7 +98,7 @@ npx prisma generate

### 2.3. Set up a global Prisma client

Create a `/lib` directory and a `prisma.ts` file inside it. This file will be used to create and export your Prisma Client instance.
In the `src` directory, create a `lib` folder and a `prisma.ts` file inside it. This file will be used to create and export your Prisma Client instance.

```terminal
mkdir -p src/lib
Expand Down Expand Up @@ -149,19 +149,19 @@ We recommend using a connection pooler (like [Prisma Accelerate](https://www.pri
If you choose not to use one, **avoid** instantiating `PrismaClient` globally in long-lived environments. Instead, create and dispose of the client per request to prevent exhausting your database connections.
:::

## 3. Set up Better-Auth
## 3. Set up Better Auth

Now it's time to integrate Better-Auth for authentication.
Now it's time to integrate Better Auth for authentication.

### 3.1. Install and configure Better-Auth
### 3.1. Install and configure Better Auth

First, install the Better-Auth core package:
First, install the Better Auth core package:

```terminal
npm install better-auth
```

Next, generate a secure secret that Better-Auth will use to sign authentication tokens. This ensures your tokens cannot be messed with.
Next, generate a secure secret that Better Auth will use to sign authentication tokens. This ensures your tokens cannot be messed with.

```terminal
npx @better-auth/cli@latest secret
Expand All @@ -170,7 +170,7 @@ npx @better-auth/cli@latest secret
Copy the generated secret and add it, along with your application's URL, to your `.env` file:

```dotenv file=.env showLineNumbers
# Better-Auth
# Better Auth
//add-start
BETTER_AUTH_SECRET=your-generated-secret
BETTER_AUTH_URL=http://localhost:3000
Expand All @@ -180,13 +180,13 @@ BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL="your-database-url"
```

Now, create a configuration file for Better-Auth at `src/lib/auth.ts`:
Now, create a configuration file for Better Auth. In the `src/lib` directory, create an `auth.ts` file:

```terminal
touch src/lib/auth.ts
```

In this file, you'll configure Better-Auth to use the Prisma adapter, which allows it to persist user and session data in your database. You will also enable email and password authentication.
In this file, you'll configure Better Auth to use the Prisma adapter, which allows it to persist user and session data in your database. You will also enable email and password authentication.

```ts file=src/lib/auth.ts
import { betterAuth } from 'better-auth'
Expand All @@ -200,7 +200,7 @@ export const auth = betterAuth({
})
```

Better-Auth also supports other sign-in methods like social logins (Google, GitHub, etc.), which you can explore in their [documentation](https://www.better-auth.com/docs/authentication/email-password).
Better Auth also supports other sign-in methods like social logins (Google, GitHub, etc.), which you can explore in their [documentation](https://www.better-auth.com/docs/authentication/email-password).

```ts file=src/lib/auth.ts
import { betterAuth } from 'better-auth'
Expand Down Expand Up @@ -240,9 +240,9 @@ export const auth = betterAuth({
```
:::

### 3.2. Add Better-Auth models to your schema
### 3.2. Add Better Auth models to your schema

Better-Auth provides a CLI command to automatically add the necessary authentication models (`User`, `Session`, `Account`, and `Verification`) to your `schema.prisma` file.
Better Auth provides a CLI command to automatically add the necessary authentication models (`User`, `Session`, `Account`, and `Verification`) to your `schema.prisma` file.

Run the following command:

Expand Down Expand Up @@ -329,16 +329,16 @@ npx prisma migrate dev --name add-auth-models

## 4. Set up the API routes

Better-Auth needs an API endpoint to handle authentication requests like sign-in, sign-up, and sign-out. You'll create a catch-all API route in Next.js to handle all requests sent to `/api/auth/[...all]`.
Better Auth needs an API endpoint to handle authentication requests like sign-in, sign-up, and sign-out. You'll create a catch-all API route in Next.js to handle all requests sent to `/api/auth/[...all]`.

First, create the necessary directory and file:
In the `src/app/api` directory, create an `auth/[...all]` folder structure and a `route.ts` file inside it:

```terminal
mkdir -p "src/app/api/auth/[...all]"
touch "src/app/api/auth/[...all]/route.ts"
```

Add the following code to the newly created `route.ts` file. This code uses a helper from Better-Auth to create Next.js-compatible `GET` and `POST` request handlers.
Add the following code to the newly created `route.ts` file. This code uses a helper from Better Auth to create Next.js-compatible `GET` and `POST` request handlers.

```ts
import { auth } from "@/lib/auth";
Expand All @@ -347,7 +347,7 @@ import { toNextJsHandler } from "better-auth/next-js";
export const { POST, GET } = toNextJsHandler(auth);
```

Next, you'll need a client-side utility to interact with these endpoints from your React components. Create a new file `src/lib/auth-client.ts`:
Next, you'll need a client-side utility to interact with these endpoints from your React components. In the `src/lib` directory, create an `auth-client.ts` file:

```terminal
touch src/lib/auth-client.ts
Expand All @@ -363,7 +363,11 @@ export const { signIn, signUp, signOut, useSession } = createAuthClient()

## 5. Set up your pages

Now, let's build the user interface for authentication. Create the pages for signing up, signing in, and a protected dashboard:
Now, let's build the user interface for authentication. In the `src/app` directory, create the following folder structure:

- `sign-up/page.tsx`
- `sign-in/page.tsx`
- `dashboard/page.tsx`

```terminal
mkdir -p src/app/{sign-up,sign-in,dashboard}
Expand Down Expand Up @@ -410,7 +414,7 @@ export default function SignUpPage() {
}
```

Now, import the `signUp` function from your Better-Auth client and add the `handleSubmit` function. This function is triggered on form submission and calls the `signUp.email` method provided by Better-Auth, passing the user's name, email, and password.
Now, import the `signUp` function from your Better Auth client and add the `handleSubmit` function. This function is triggered on form submission and calls the `signUp.email` method provided by Better Auth, passing the user's name, email, and password.

```tsx file=src/app/sign-up/page.tsx
"use client";
Expand Down Expand Up @@ -611,7 +615,7 @@ export default function SignInPage() {
}
```

Add the `handleSubmit` function, this time importing and using the `signIn.email` method from Better-Auth.
Add the `handleSubmit` function, this time importing and using the `signIn.email` method from Better Auth.

```tsx file=src/app/sign-in/page.tsx
"use client";
Expand Down Expand Up @@ -778,7 +782,7 @@ export default function DashboardPage() {
}
```

Import the `useSession` hook from your Better-Auth client. This hook is the key to managing authentication state on the client side. It provides the session data and a pending status.
Import the `useSession` hook from your Better Auth client. This hook is the key to managing authentication state on the client side. It provides the session data and a pending status.

```tsx file=src/app/dashboard/page.tsx
"use client";
Expand Down Expand Up @@ -816,7 +820,7 @@ export default function DashboardPage() {
const router = useRouter();
const { data: session, isPending } = useSession();

//add-start: redirect if not signed in
//add-start
useEffect(() => {
if (!isPending && !session?.user) {
router.push("/sign-in");
Expand Down Expand Up @@ -851,7 +855,7 @@ export default function DashboardPage() {
}
}, [isPending, session, router]);

//add-start: loading and redirect states
//add-start
if (isPending)
return <p className="text-center mt-8 text-white">Loading...</p>;
if (!session?.user)
Expand Down Expand Up @@ -890,7 +894,7 @@ export default function DashboardPage() {
if (!session?.user)
return <p className="text-center mt-8 text-white">Redirecting...</p>;

//add-start: destructure user from session
//add-start
const { user } = session;
//add-end

Expand All @@ -899,7 +903,7 @@ export default function DashboardPage() {
<h1 className="text-2xl font-bold">Dashboard</h1>
<p>Welcome, {user.name || "User"}!</p>
<p>Email: {user.email}</p>
{/* add-start: sign out button */}
{/* add-start */}
<button
onClick={() => signOut()}
className="w-full bg-white text-black font-medium rounded-md px-4 py-2 hover:bg-gray-200"
Expand Down Expand Up @@ -967,7 +971,7 @@ npx prisma studio

:::success

Congratulations! You now have a fully functional authentication system built with Better-Auth, Prisma, and Next.js.
Congratulations! You now have a fully functional authentication system built with Better Auth, Prisma, and Next.js.

:::

Expand All @@ -981,6 +985,6 @@ Congratulations! You now have a fully functional authentication system built wit

## Further reading

- [Better-Auth documentation](https://www.better-auth.com/docs)
- [Better Auth documentation](https://www.better-auth.com/docs)
- [Prisma documentation](/orm/overview/introduction)
- [Next.js App Router](https://nextjs.org/docs/app)
2 changes: 1 addition & 1 deletion content/800-guides/380-vercel-app-deployment.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Experience the instant deployment flow with [our interactive demo](https://pris.

**Available examples:**
- **Next.js + Prisma**: Basic full-stack application with database integration
- **Next.js + Prisma + Better-Auth**: Complete application with authentication using [Better-Auth](https://www.better-auth.com/)
- **Next.js + Prisma + Better Auth**: Complete application with authentication using [Better Auth](https://www.better-auth.com/)

**Demo features:**

Expand Down
Loading