Invite users to an organization
Organization members with appropriate permissions can invite new users to their organization and manage those invitations. When an administrator invites a new member, an invitation email is sent out. The invitation recipient can be either an existing user of your application or a new user. If the latter is true, the user will need to register in order to accept the invitation.
In React and Next.js applications, the useOrganization()
hook returns the organization
property, which is then used to call organization.inviteMember()
passing in the recipient's email address and desired role.
Administrators are also able to revoke organization invitations for users that have not yet joined, which will prevent the user from becoming an organization member. This is done by calling the revoke()
method on the invitations in the invitationList
returned by the useOrganization()
hook.
Usage
An example implementation in Next.js for inviting users and revoking pending invitations:
import { useOrganization } from '@clerk/nextjs'; import { useState } from 'react'; function InviteMember() { const { organization } = useOrganization(); const [emailAddress, setEmailAddress] = useState(''); const [role, setRole] = useState<'org:member' | 'admin'>('org:member'); const [disabled, setDisabled] = useState(false); const onSubmit = async e => { e.preventDefault(); setDisabled(true); await organization.inviteMember({ emailAddress, role }); setEmailAddress(''); setRole('org:member'); setDisabled(false); }; return ( <form onSubmit={onSubmit}> <input type="text" placeholder="Email address" value={emailAddress} onChange={e => setEmailAddress(e.target.value)} /> <label> <input type="radio" checked={role === 'admin'} onChange={() => { setRole('admin'); }} />{' '} Admin </label> <label> <input type="radio" checked={role === 'org:member'} onChange={() => { setRole('org:member'); }} />{' '} Member </label>{' '} <button type="submit" disabled={disabled}> Invite </button> </form> ); } export default function InvitationList() { const { invitationList } = useOrganization({ invitationList: {} }); if (!invitationList) { return null; } const revoke = async inv => { await inv.revoke(); }; return ( <div> <h2>Invite member</h2> <InviteMember /> <h2>Pending invitations</h2> <ul> {invitationList.map(i => ( <li key={i.id}> {i.emailAddress} <button onClick={() => revoke(i)}>Revoke</button> </li> ))} </ul> </div> ); }
Custom redirect url
When creating an organization invitation and using Clerk's Next.js, Remix, or Backend SDKs, you can specify a custom redirect URL. After users click on organization invitation link and the ticket is verified, they will get redirected to that URL. The URL will contain two important query parameters added by Clerk: __clerk_ticket
and __clerk_status
.
The __clerk_ticket
query parameter will hold the actual ticket token, which can be used during sign-in and sign-up flows in order to complete the organization invitation flow.
The __clerk_status
query parameter is the outcome of the ticket verification and will contain one of three values:
sign_in
indicates the user already exists in your application. You should create a sign-in ticket in order to complete the flow.sign_up
indicates the user doesn't already exist in your application. You should create a sign-up ticket in order to complete the flow.complete
indicates the user already exists in your application, and was signed in. The flow has been completed and no further actions are required.
An example implementation on how to create an invitation by providing a redirect url using Clerk backend SDK:
clerkClient.organizations.createOrganizationInvitation({ organizationId: 'org_2S7G8yGKaPp7nWn52idDTnxXkWW', emailAddress: 'member@myapp.com', inviterUserId: 'user_2ULtoAaFHBSep6Gnr5bphZXITmD', role: 'org:member', redirectUrl: "https://myapp.com/invite-accepted" })