BETTER-AUTH. UI
Components

<OrganizationInvitationEmail />

Email template component that invites a user to join an organization.

Usage

import { OrganizationInvitationEmail } from "@better-auth-ui/heroui/email"
import { render } from "@react-email/render"

const html = await render(
  // biome-ignore lint/a11y/useValidAriaRole: `role` is a prop on the email component, not an ARIA role.
  <OrganizationInvitationEmail
    url="https://better-auth-ui.com/settings/organizations"
    email="[email protected]"
    inviterName="Jane Doe"
    inviterEmail="[email protected]"
    organizationName="Acme Inc."
    role="member"
    appName="Better Auth UI"
    logoURL={{
      light: "/favicon-96x96.png",
      dark: "/favicon-96x96-inverted.png"
    }}
    expirationHours={48}
    darkMode={true}
    poweredBy={true}
  />
)

Server setup

Wire the email into the Better Auth organization plugin via sendInvitationEmail. Point url at the settings page where pending invitations are listed — better-auth-ui renders them under /settings/organizations.

auth.ts
import { OrganizationInvitationEmail } from "@better-auth-ui/heroui/email"
import { render } from "@react-email/render"
import { betterAuth } from "better-auth"
import { organization } from "better-auth/plugins"

const baseUrl = process.env.BETTER_AUTH_URL!

export const auth = betterAuth({
  plugins: [
    organization({
      async sendInvitationEmail(data) {
        const html = await render(
          <OrganizationInvitationEmail
            url={`${baseUrl}/settings/organizations`}
            email={data.email}
            inviterName={data.inviter.user.name}
            inviterEmail={data.inviter.user.email}
            organizationName={data.organization.name}
            organizationLogoURL={data.organization.logo ?? undefined}
            role={data.role}
            appName="My App"
            poweredBy
          />
        )

        await sendEmail({
          to: data.email,
          subject: `You're invited to ${data.organization.name}`,
          html
        })
      }
    })
  ]
})

url should always resolve to {baseUrl}/settings/organizations — that's where the <UserInvitations /> table inside <OrganizationsSettings /> renders pending invitations the user can accept or reject.

Props

Prop

Type

Features

  • Inviter name and email display
  • Organization name and optional organization logo
  • Role being offered (e.g. member, admin, owner)
  • Accept invitation button linking to the settings invitations page
  • Fallback URL for manual copy/paste
  • Optional expiration time
  • Security notice for unexpected invitations
  • Customizable branding and styling
  • Support for light/dark mode themes
  • Localization support

Last updated on

On this page