In this guide, we will implement Anonymous Login for a modern web application using a secure and developer-friendly stack. This feature will allow users to interact with your app without requiring immediate registration or authentication. By the end of this tutorial, your application will support seamless anonymous sessions that can be converted to authenticated accounts, providing an enhanced user experience while maintaining security and scalability.
Tech Stack
Here’s the technology stack we’ll be using:
- Better_Auth v1: A lightweight and extensible TypeScript authentication library.
- Next.js: A powerful React framework for building server-rendered applications.
- Prisma: A modern ORM for efficient and type-safe database interaction.
- ShadCN: A utility-first component library for rapid UI development.
- TailwindCSS: A popular CSS framework for building modern user interfaces.
- Resend: A reliable email service for sending OTPs.
Prerequisites
Before proceeding, ensure you have the following ready:
- Node.js (LTS version) installed.
- A package manager like npm, yarn, or pnpm (we'll use
pnpm
in this guide). - A PostgreSQL database instance (local or hosted, such as Supabase or PlanetScale).
- If you're working locally, Docker is a great way to set this up.
- Familiarity with TypeScript, Next.js, and Prisma.
Cloning the Starter Project:
This guide builds upon functionality such as Email-Password Authentication and Email Verification. You can:
- Start from scratch by following these guides:
- Or, clone the starter project:
git clone -b feat-username https://github.com/Daanish2003/better_auth_nextjs.git
Navigate to the project directory and install dependencies:
pnpm install
Setup
1. Configure the .env
File
Create a .env
file in the root of your project and add these configurations:
# Authentication settings
BETTER_AUTH_SECRET="your-secret-key" # Replace with a secure key
BETTER_AUTH_URL="http://localhost:3000"
NEXT_PUBLIC_APP_URL="http://localhost:3000"
# Database settings
POSTGRES_PASSWORD="your-password"
POSTGRES_USER="your-username"
DATABASE_URL="postgresql://your-username:your-password@localhost:5432/mydb?schema=public"
# Resend API Key
RESEND_API_KEY="your-resend-api-key"
If you're using Docker for PostgreSQL, start the container:
docker compose up -d
Step 1: Update schema.prisma
file
Open schema.prisma
file in your project folder and then update the user
model in schema by adding the isAnonymous
column with optional type string to it.
model User {
id String @id @default(cuid())
name String
email String
emailVerified Boolean @default(false)
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
twoFactorEnabled Boolean @default(false)
username String?
// Add anonymous column to user model
isAnonymous Boolean?
Session Session[]
Account Account[]
TwoFactor TwoFactor[] // if you implemented 2FA add this column
@@unique([email])
@@map("user")
}
Then, Generate and migrate the prisma file using command below
pnpx prisma generate
pnpx prisma migrate dev --name anonymous
Step 2: Update auth.ts
and auth-client.ts
file
Open auth.ts
file in your project repository and then add the anonymous()
plugin into plugin array of betterAuth function.
// src/lib/auth.ts
import { betterAuth } from "better-auth"
import { username } from "better-auth/plugins"
const auth = betterAuth({
// other config options
plugins: [
// other plugins
anonymous({
// optional to add this
emailDomainName: "exmaple.com" // Adding the email domain name to user
//Note: user model, account model and session model is automatically transfer when user signup using their email.
// There is no need to transfer the user, account, session model table data.
// If you have other data of user then use the option below to transfer the data
onLinkAccount: () => {
// if you want transfer the guest users all the data like preference, carts, or items after login. Please use this option to update data in your database
}
})
]
})
Then, Open auth-client.ts
file in your project repository and add anonymousClient()
plugin function to the array of plugins
// src/lib/auth-client.ts
import { createAuthClient } from "better-auth/client"
import { anonymousClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_APP_URL,
plugins: [
// other plugin options
anonymousClient()
]
})
export const {
signIn,
signOut,
signUp,
useSession
} = authClient;
Step 4: Create anonymous-button
Component
Create a anonymous-button.tsx
inside the components/auth/
folder and paste the code from below
// src/components/auth/anonymous-button.tsx
import React from 'react'
import { Button } from '../ui/button'
import { User } from 'lucide-react'
import { authClient } from '@/lib/auth-client'
import { useAuthState } from '@/hooks/useAuthState'
import { useRouter } from 'next/navigation'
const AnonymousButton = () => {
const router = useRouter();
// handler error, success, and loading state
const {setSuccess, setError, setLoading, resetState } = useAuthState();
const handleSignInAnonymous = async () => {
try {
await authClient.signIn.anonymous({
fetchOptions: {
onSuccess: () => {
setSuccess("LoggedIn successfully")
router.replace('/')
},
onError: (ctx) => setError(ctx.error.message),
onRequest: () => {
resetState()
setLoading(true)
},
onResponse: () => setLoading(true)
}
})
} catch(error) {
console.log(error)
setError("Something went wrong")
}
}
return (
<Button className='w-28' onClick={handleSignInAnonymous}>
<User />
Guest
</Button>
)
}
export default AnonymousButton
This Component handles the logic of anonymous
login
Step 5: Update SignIn component and Signup component
SignUp Component:
// src/components/auth/sign-up.tsx
"use client"
// other imports
import AnonymousButton from "./anonymos-button";
const SignUp = () => {
// Other functions and logics
return (
<CardWrapper
cardTitle='SignUp'
cardDescription='Create an new account'
cardFooterLink='/signin'
cardFooterDescription='Already have an account?'
cardFooterLinkTitle='Signin'
>
<Form {...form}>
<form className='space-y-4' onSubmit={form.handleSubmit(onSubmit)}>
{/* FormFields example: Email, password and other*/}
{/* Add the Anonymous login button below inside the form*/}
<AnonymousButton />
</form>
</Form>
</CardWrapper>
)
}
export default SignUp
Add AnonymousButton
component to SignUp
:
- By clicking the anonymous button user were able to login anonymously
SignIn Component
// components/auth/sign-in.tsx
"use client";
// other imports
import AnonymousButton from "./anonymos-button";
const SignIn = () => {
// other function
return (
<CardWrapper
cardTitle="Sign In"
cardDescription="Enter your email or username below to login to your account"
cardFooterDescription="Don't have an account?"
cardFooterLink="/signup"
cardFooterLinkTitle="Sign up"
>
<Form {...form}>
<form className="space-y-4" onSubmit={form.handleSubmit(onSubmit)}>
{/* Email or Username Field */}
{/* All other exisitng formfields like password and form message */}
{/* Add Anonynous button here */}
<AnonymousButton />
</form>
</Form>
</CardWrapper>
);
};
export default SignIn;
Add AnonymousButton
to SignIn
:
- By clicking the anonymous button user were able to login anonymously
Step 6: Run your application:
Start your development server:
pnpm dev
Navigate to your sign-up
route and sign-in
route and try login anonymously
Conclusion
Congratulations! 🎉 You’ve successfully implemented Anonymous Login in your application. With this feature, users can explore and interact with your app without the need for immediate registration, enhancing accessibility and user engagement. Moreover, by enabling a smooth transition from anonymous sessions to authenticated accounts, your app ensures both flexibility and security for its users.
Blog Links:
Username and Password auth using BetterAuth: https://dev.to/daanish2003/username-and-password-authentication-with-betterauth-nextjs-prisma-shadcn-and-tailwindcss-1hc6
Two Factor Authentication using BetterAuth: https://dev.to/daanish2003/two-factor-authentication-using-betterauth-nextjs-prisma-shadcn-and-resend-1b5p
Forgot and ResetPassword using BetterAuth: https://dev.to/daanish2003/forgot-and-reset-password-using-betterauth-nextjs-and-resend-ilj
Email Verification Blog: https://dev.to/daanish2003/email-verification-using-betterauth-nextjs-and-resend-37gn
Email And Password with Better_Auth: https://dev.to/daanish2003/email-and-password-auth-using-betterauth-nextjs-prisma-shadcn-and-tailwindcss-hgc
OAuth Blog: https://dev.to/daanish2003/oauth-using-betterauth-nextjs-prisma-shadcn-and-tailwindcss-45bp
Reference Links:
Better_Auth Docs: https://www.better-auth.com/
pnpm Docs: https://pnpm.io/
Docker Docs: https://docs.docker.com/
Prisma Docs: https://www.prisma.io/docs/getting-started
Shadcn Docs: https://ui.shadcn.com/
Next.js Docs: https://nextjs.org/
Tailwindcss Docs: https://tailwindcss.com/
Github repository: https://github.com/Daanish2003/better_auth_nextjs
Top comments (0)