### Full Example: Activate Invite Page (Next.js App Router)
Source: https://www.better-invite.com/llms.mdx/docs/examples
A complete example for an `/activate-invite/[token]` page using Next.js App Router. It handles server-side authentication checks, redirects to login if necessary, displays Accept/Reject UI, activates the invite upon acceptance, and redirects after the action.
```tsx
import { redirect } from "next/navigation";
import Link from "next/link";
import { auth } from "@/lib/auth";
import ActivateInviteClient from "./ui";
export default async function ActivateInvitePage({ params, }: { params: { token: string }; }) {
const session = await auth.api.getSession();
const token = params.token;
// Not logged in: redirect to login and return here after authentication
if (!session?.user) {
redirect(`/login?callbackUrl=/activate-invite/${token}`);
}
return (
You have been invited
Accepting this invite will activate it and apply the role or membership configured by the sender.
Not you?{" "} Sign out
);
}
```
--------------------------------
### Install Better Invite Package
Source: https://www.better-invite.com/llms.mdx/docs/installation
Add the invite plugin to your project using your preferred package manager.
```bash
npm install better-invite
```
```bash
pnpm add better-invite
```
```bash
yarn add better-invite
```
```bash
bun add better-invite
```
--------------------------------
### GET /api/invites/get
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Retrieves basic information about a specific invitation.
```APIDOC
## GET /api/invites/get
### Description
Get basic information about an invitation.
### Method
GET
### Query Parameters
- **token** (string) - Required - The invite token to look up.
```
--------------------------------
### Define Get Invite Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for retrieving invite information, requiring the invite token.
```typescript
type getInvite = {
/**
* The invite token to look up.
*/
token: string
}
```
--------------------------------
### GET /api/invites/list
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Lists all private invitations for the current user with optional filtering and sorting.
```APIDOC
## GET /api/invites/list
### Description
List all (private) invitations for the current user.
### Method
GET
### Query Parameters
- **searchValue** (string) - Optional - The value to search for.
- **searchField** ("name" | "email" | "domainWhitelist") - Optional - The field to search in.
- **searchOperator** ("contains" | "starts_with" | "ends_with") - Optional - The operator to use for the search.
- **limit** (number) - Optional - Number of invitations to return.
- **offset** (number) - Optional - Offset to start from.
- **sortBy** (string) - Optional - Field to sort by.
- **sortDirection** ("asc" | "desc") - Optional - Sort direction.
- **filterField** (string) - Optional - Field to filter by.
- **filterValue** (string|number|boolean) - Optional - Value to filter by.
- **filterOperator** ("eq" | "ne" | "lt" | "lte" | "gt" | "gte") - Optional - Operator to use for the filter.
```
--------------------------------
### Migrate Database for Invite Plugin
Source: https://www.better-invite.com/llms.mdx/docs/installation
Run database migrations or generate the schema to include necessary fields and tables for the invite plugin. Use the `@better-auth/cli` for this.
```bash
npx @better-auth/cli migrate
```
```bash
pnpm dlx @better-auth/cli migrate
```
```bash
yarn dlx @better-auth/cli migrate
```
```bash
bun x @better-auth/cli migrate
```
--------------------------------
### Generate Schema for Invite Plugin
Source: https://www.better-invite.com/llms.mdx/docs/installation
Generate the database schema to include necessary fields and tables for the invite plugin. Use the `@better-auth/cli` for this.
```bash
npx @better-auth/cli generate
```
```bash
pnpm dlx @better-auth/cli generate
```
```bash
yarn dlx @better-auth/cli generate
```
```bash
bun x @better-auth/cli generate
```
--------------------------------
### Add Client Plugins for Better Auth
Source: https://www.better-invite.com/llms.mdx/docs/installation
Integrate the `adminClient` and `inviteClient` into your Better Auth client configuration.
```typescript
import { createAuthClient } from "better-auth/client";
import { adminClient } from "better-auth/client/plugins";
import { inviteClient } from "better-invite";
// [!code highlight]
const authClient = createAuthClient({
//... other options
plugins: [
adminClient(),
inviteClient(),
// [!code highlight]
],
});
```
--------------------------------
### POST /api/invites/create
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Creates a new invitation with specified role, token type, and redirection settings.
```APIDOC
## POST /api/invites/create
### Description
Creates a new invitation for a user. If an email is provided, the invite is treated as private.
### Method
POST
### Request Body
- **role** (string) - Required - The role to give the invited user.
- **email** (string) - Optional - The email address of the user to send an invitation email to.
- **tokenType** ("token" | "code" | "custom") - Optional - Type of token to use.
- **redirectToSignUp** (string) - Optional - URL to redirect for account creation.
- **redirectToSignIn** (string) - Optional - URL to redirect for role upgrade.
- **maxUses** (number) - Optional - Number of times an invitation can be used.
- **expiresIn** (number) - Optional - Seconds the token is valid for.
- **redirectToAfterUpgrade** (string) - Optional - URL to redirect after upgrade.
- **shareInviterName** (boolean) - Optional - Whether to share the inviter's name.
- **senderResponse** ("token" | "url") - Optional - How the sender receives the token.
- **senderResponseRedirect** ("signUp" | "signIn") - Optional - Redirect destination if no email is provided.
- **customInviteUrl** (string) - Optional - Custom URL template.
- **inviteUrlType** ("api" | "custom") - Optional - URL type to send in email.
```
--------------------------------
### Configure Invite Plugin in Auth
Source: https://www.better-invite.com/llms.mdx/docs/installation
Integrate the invite plugin into your auth configuration. Ensure the admin plugin is also present. Customize invitation behavior with options like `defaultRedirectAfterUpgrade` and `sendUserInvitation`.
```typescript
import { betterAuth } from "better-auth";
import { admin } from "better-auth/plugins";
import { invite } from "better-invite";
// [!code highlight]
export const auth = betterAuth({
// ... other config options
plugins: [
admin({
ac,
roles: {
user,
admin
},
defaultRole: "user",
}),
invite({
// [!code highlight]
defaultRedirectAfterUpgrade: "/auth/invited?token={token}",
// Show the user their new role or account
async sendUserInvitation({ email, role, url, token, newAccount }) {
if (newAccount) void sendInvitationEmail(role as RoleType, email, url);
void sendRoleUpgradeEmail(role as RoleType, email, url);
},
}),
],
});
```
--------------------------------
### Create an invite
Source: https://www.better-invite.com/llms.mdx/docs/basic-usage
Use the invite.create method to generate a new invite. Providing an email makes the invite private, while omitting it makes it public.
```ts
const res = authClient.invite.create({
role: "user",
email: "test@test.com" // If email is present, the invite is private
})
```
--------------------------------
### Upgrade Better Auth with bun
Source: https://www.better-invite.com/llms.mdx/docs/reference/troubleshooting
Use this command to upgrade the Better Auth package to the latest version using bun. This resolves issues related to missing exports like 'expireCookie'.
```bash
bun add better-auth@latest
```
--------------------------------
### POST /api/invites/activate
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Activates an invitation using a provided token.
```APIDOC
## POST /api/invites/activate
### Description
Activates an invitation token to allow a user to sign in or sign up.
### Method
POST
### Request Body
- **token** (string) - Required - The invite token.
- **callbackURL** (string) - Optional - Where to redirect the user after sign in/up.
```
--------------------------------
### Activate an invite
Source: https://www.better-invite.com/llms.mdx/docs/basic-usage
Use the invite.activate method to process an invite token. If the user is not signed in, they will be redirected to the specified callback URL.
```ts
const res = await authClient.invite.activate({
callbackURL: "/auth/sign-in-or-sign-up", // The user will be redirected here if they need to sign in or sign up
token: "token123",
});
```
--------------------------------
### Define Create Invite Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for creating a new invitation, including optional parameters for role, email, token type, redirect URLs, usage limits, expiration, and sharing settings.
```typescript
type createInvite = {
/**
* The role to give the invited user.
*/
role: string
/**
* The email address of the user to send a invitation email to.
*/
email?: string // If email is present, the invite is private
/**
* Type of token to use, 24 character token,
* 6 digit code or custom options.generateToken.
* @default options.defaultTokenType
*/
tokenType?: "token" | "code" | "custom"
/**
* The URL to redirect the user to create their account.
* If the token isn't valid or expired, it'll be redirected with a query parameter
* `?error=INVALID_TOKEN`.
* If the token is valid, it'll be redirected with a query parameter
* `?token=VALID_TOKEN`.
*
* @default options.defaultRedirectTo
*/
redirectToSignUp?: string
/**
* The URL to redirect the user to upgrade their role.
* If the token isn't valid or expired, it'll be redirected with a query parameter
* `?error=INVALID_TOKEN`.
* If the token is valid, it'll be redirected with a query parameter
* `?token=VALID_TOKEN`.
*
* @default options.defaultRedirectToSignIn
*/
redirectToSignIn?: string
/**
* The number of times an invitation can be used.
*
* @default options.defaultMaxUses
*/
maxUses?: number
/**
* Number of seconds the invitation token is valid for.
*
* @default options.invitationTokenExpiresIn
*/
expiresIn?: number
/**
* The URL to redirect the user to after upgrading their role (if the user is already logged in).
* {token} will be replaced with the user's actual token.
*
* @default options.defaultRedirectAfterUpgrade
*/
redirectToAfterUpgrade?: string
/**
* Whether the inviter's name should be shared with the invitee.
*
* When enabled, the person receiving the invitation will see
* the name of the user who created the invitation.
*
* @default options.defaultShareInviterName
*/
shareInviterName?: boolean
/**
* How should the sender receive the token.
* (sender only receives a token if no email is provided)
*
* @default options.defaultSenderResponse
*/
senderResponse?: "token" | "url"
/**
* Where should we redirect the user?
* (only if no email is provided)
*
* @default options.defaultSenderResponseRedirect
*/
senderResponseRedirect?: "signUp" | "signIn"
/**
* If inviteUrlType is set to custom, this will be used
* Use {token} and {callbackUrl}, this will be replaced with their values
*/
customInviteUrl?: string
/**
* The url to send in the email to the user
*
* @default api
*/
inviteUrlType?: "api" | "custom"
}
```
--------------------------------
### Define Activate Invite Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for activating an invite, requiring a token and an optional callback URL for redirection.
```typescript
type activateInvite = {
/**
* Where to redirect the user after sing in/up
*/
callbackURL?: string
/**
* The invite token
*/
token: string
}
```
--------------------------------
### Configure Rate Limiting
Source: https://www.better-invite.com/llms.mdx/docs/core/extras
Set global and route-specific rate limits for invite plugin operations.
```ts
import { betterAuth } from "better-auth";
export const auth = betterAuth({
//...other options
rateLimit: {
window: 60,
max: 100,
customRules: {
"/invite/activate": {
window: 10,
max: 3,
},
"/invite/create": {
window: 10,
max: 3,
},
},
},
})
```
--------------------------------
### Activate Invite Client Component
Source: https://www.better-invite.com/llms.mdx/docs/examples
A Next.js client component that manages the invite activation lifecycle, including loading states and error handling.
```tsx
"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { authClient } from "@/lib/auth-client"; export default function ActivateInviteClient({ token }: { token: string }) { const router = useRouter(); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); async function acceptInvite() { setLoading(true); setError(null); try { const res = await authClient.invite.activate({ token }); // If your plugin returns a redirect URL, prefer it. const redirectTo = (res as any)?.redirectTo ?? (res as any)?.data?.redirectTo ?? "/auth/invited"; router.push(redirectTo); router.refresh(); } catch (err: any) { setError(err?.message ?? "Failed to activate invite."); setLoading(false); } } function rejectInvite() { router.push("/"); } return (
{error ?
{error}
: null}
); }
```
--------------------------------
### Upgrade Better Auth with pnpm
Source: https://www.better-invite.com/llms.mdx/docs/reference/troubleshooting
Use this command to upgrade the Better Auth package to the latest version using pnpm. This resolves issues related to missing exports like 'expireCookie'.
```bash
pnpm add better-auth@latest
```
--------------------------------
### Define Activate Invite Callback Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for the internal activate invite callback, including an optional callback URL and the invite token. This is primarily for internal use.
```typescript
type activateInviteCallback = {
/**
* Where to redirect the user after sing in/up
*/
callbackURL?: string
/**
* @ignore
* The invite token
*/
token: string
}
```
--------------------------------
### Upgrade Better Auth with npm
Source: https://www.better-invite.com/llms.mdx/docs/reference/troubleshooting
Use this command to upgrade the Better Auth package to the latest version using npm. This resolves issues related to missing exports like 'expireCookie'.
```bash
npm install better-auth@latest
```
--------------------------------
### Upgrade Better Auth with yarn
Source: https://www.better-invite.com/llms.mdx/docs/reference/troubleshooting
Use this command to upgrade the Better Auth package to the latest version using yarn. This resolves issues related to missing exports like 'expireCookie'.
```bash
yarn add better-auth@latest
```
--------------------------------
### Define List Invites Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for listing invitations, with parameters for searching, filtering, sorting, and pagination.
```typescript
type listInvites = {
/**
* The value to search for
*/
searchValue?: string
/**
* The field to search in, defaults to email. Can be `email`, `name` or `domainWhitelist`
*/
searchField?: "name" | "email" | "domainWhitelist"
/**
* The operator to use for the search. Can be `contains`, `starts_with` or `ends_with`
*/
searchOperator?: "contains" | "starts_with" | "ends_with"
/**
* The numbers of invitations to return
*/
limit?: number
/**
* The offset to start from
*/
offset?: number
/**
* The field to sort by
*/
sortBy?: string
/**
* The direction to sort by. Can be `asc` or `desc`
*/
sortDirection?: "asc" | "desc"
/**
* The field to filter by
*/
filterField?: string
/**
* The value to filter by
*/
filterValue?: string | number | boolean
/**
* The operator to use for the filter. Can be `eq`, `ne`, `lt`, `lte`, `gt` or `gte`
*/
filterOperator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte"
}
```
--------------------------------
### Redirect to Login if Not Authenticated
Source: https://www.better-invite.com/llms.mdx/docs/examples
When a user clicks an invite link and is not logged in, redirect them to the login page. The `callbackUrl` parameter ensures they return to the invite activation page after successful login.
```typescript
authClient.signIn({
callbackUrl: `/activate-invite/${token}`,
});
```
--------------------------------
### Customize Plugin Schema
Source: https://www.better-invite.com/llms.mdx/docs/core/extras
Rename database tables and fields for the invite plugin to match existing database naming conventions.
```ts
import { invite } from "better-invite";
const auth = betterAuth({
plugins: {
invite({
schema: {
invite: {
modelName: "custom_invite",
fields: {
token: "custom_token",
createdAt: "created_at",
expiresAt: "expires_at",
maxUses: "max_uses",
createdByUserId: "creator_id",
redirectToAfterUpgrade: "redirect_url",
shareInviterName: "share_name",
email: "invite_email",
role: "invite_role",
}
},
inviteUse: {
modelName: "customInviteUse",
fields: {
inviteId: "invite_id",
usedAt: "usedAt",
usedByUserId: "used_by_user_id"
}
}
}
})
}
});
```
--------------------------------
### Set Default Custom Invite URL
Source: https://www.better-invite.com/llms.mdx/docs/examples
Configure Better Auth to use a custom URL for all invite links. This is recommended for a consistent user experience. Ensure your `sendUserInvitation` function correctly formats the invite URL.
```typescript
import { betterAuth } from "better-auth";
import { admin } from "better-auth/plugins";
import { invite } from "better-invite";
export const auth = betterAuth({
plugins: [
admin({
// ... your admin config
}),
invite({
defaultMaxUses: 1,
defaultRedirectAfterUpgrade: "/auth/invited",
// All invite links will now point to:
// /activate-invite/${token}
defaultCustomInviteUrl: "/activate-invite",
async sendUserInvitation({ email, role, url, token, newAccount }) {
// `url` uses your custom invite URL and automatically appends the token: /activate-invite/${token}
if (newAccount) {
await sendInvitationEmail(role, email, url);
return;
}
await sendRoleUpgradeEmail(role, email, url);
},
}),
],
});
```
--------------------------------
### Activate Invite
Source: https://www.better-invite.com/llms.mdx/docs/examples
Call this function when a user explicitly accepts an invite. This action confirms the invitation and applies the associated role or membership.
```typescript
await authClient.invite.activate({
token
});
```
--------------------------------
### POST /api/invites/reject
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Rejects an existing invitation token.
```APIDOC
## POST /api/invites/reject
### Description
Rejects an invitation token.
### Method
POST
### Request Body
- **token** (string) - Required - The invite token to reject.
```
--------------------------------
### Invite activation response for authenticated users
Source: https://www.better-invite.com/llms.mdx/docs/basic-usage
The API response when an invite is activated by a user who is already signed in.
```ts
{
status: true,
message: "Invite activated successfully",
}
```
--------------------------------
### Override Invite URL for a Single Invite
Source: https://www.better-invite.com/llms.mdx/docs/examples
Create a specific invite with a custom URL, useful when only certain invites require a custom UI. This allows for targeted customization without affecting the default behavior.
```typescript
await authClient.invite.create({
email: "person@example.com",
role: "admin",
customInviteUrl: "/activate-invite",
});
```
--------------------------------
### Invite activation response for unauthenticated users
Source: https://www.better-invite.com/llms.mdx/docs/basic-usage
The API response when an invite is activated by a user who is not yet signed in.
```ts
{
status: true,
message: "Invite activated successfully",
action: "SIGN_IN_UP_REQUIRED",
redirectTo: "/auth/sign-in-or-sign-up",
}
```
--------------------------------
### Reject Invite
Source: https://www.better-invite.com/llms.mdx/docs/examples
Call this function if a user chooses to reject an invite. This action formally declines the invitation.
```typescript
await authClient.invite.reject({
token
});
```
--------------------------------
### Define Reject Invite Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for rejecting an invite, which requires the invite token.
```typescript
type rejectInvite = {
/**
* The invite token to reject.
*/
token: string
}
```
--------------------------------
### Configure Cookie Prefix
Source: https://www.better-invite.com/llms.mdx/docs/core/extras
Change the default cookie prefix used by the invite plugin via the advanced options.
```ts
import { betterAuth } from "better-auth";
export const auth = betterAuth({
advanced: {
cookiePrefix: "my-app"
}
});
```
--------------------------------
### Public invite response
Source: https://www.better-invite.com/llms.mdx/docs/basic-usage
The API response structure for a public invite, which returns a token or URL.
```ts
{
status: true,
message: "token", // The invite token or URL
}
```
--------------------------------
### POST /api/invites/cancel
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Cancels an existing invitation token.
```APIDOC
## POST /api/invites/cancel
### Description
Cancels an invitation token.
### Method
POST
### Request Body
- **token** (string) - Required - The invite token to cancel.
```
--------------------------------
### Define Cancel Invite Type
Source: https://www.better-invite.com/llms.mdx/docs/core/api
Defines the structure for canceling an invite, requiring the invite token.
```typescript
type cancelInvite = {
/**
* The invite token to cancel.
*/
token: string
}
```
--------------------------------
### Private invite response
Source: https://www.better-invite.com/llms.mdx/docs/basic-usage
The API response structure for a private invite, indicating that an email has been sent.
```ts
{
status: true,
message: "The invitation was sent",
}
```
--------------------------------
### Customize Cookie Name
Source: https://www.better-invite.com/llms.mdx/docs/core/extras
Override the default invite token cookie name using the advanced cookies configuration.
```ts
import { betterAuth } from "better-auth";
export const auth = betterAuth({
advanced: {
cookies: {
invite_token: {
name: "custom_invite_token"
}
}
}
});
```
--------------------------------
### TypeScript Error: expireCookie Not Found
Source: https://www.better-invite.com/llms.mdx/docs/reference/troubleshooting
This error occurs when the Better Invite plugin is used with an older version of Better Auth that does not export the 'expireCookie' function. Ensure Better Auth is updated to v1.4.13 or newer.
```typescript
import { createAuthMiddleware } from "better-auth/api";
import { expireCookie } from "better-auth/cookies";
...
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.