### 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.