Les emails d’invitation d’équipe sont essentiels pour la croissance d’un produit SaaS. Une invitation bien conçue transforme les destinataires en utilisateurs actifs. Voici comment optimiser votre flux d’invitation.
Anatomie de l’email d’invitation
Éléments essentiels
interface TeamInvitation {
inviter: {
name: string;
email: string;
avatarUrl?: string;
};
organization: {
name: string;
logoUrl?: string;
};
invitee: {
email: string;
role: string;
};
invitation: {
id: string;
expiresAt: Date;
message?: string;
};
}
Modèle à forte conversion
await sendEmail({
to: invitee.email,
subject: `${inviter.name} invited you to join ${org.name}`,
template: 'team-invitation',
data: {
inviter,
organization: org,
role: invitee.role,
personalMessage: invitation.message,
acceptUrl: `${baseUrl}/invitations/${invitation.id}/accept`,
expiresAt: invitation.expiresAt,
previewText: `Join ${org.name} on YourApp`
}
});
Optimisation de la conversion
Preuve sociale
// Include team context
const teamContext = {
teamSize: org.memberCount,
recentActivity: `${org.activeMembers} team members active this week`,
popularFeatures: await getOrgTopFeatures(org.id)
};
Urgence sans pression
// Soft expiration
const expirationCopy = {
'7days': 'This invitation expires in 7 days',
'3days': 'Expires in 3 days',
'1day': 'Expires tomorrow',
'expired': 'This invitation has expired'
};
Séquence de relance
const invitationReminders = [
{
daysAfter: 3,
subject: `Reminder: ${inviter.name} invited you to ${org.name}`,
template: 'invitation-reminder-1'
},
{
daysAfter: 6,
subject: `Your invitation to ${org.name} expires soon`,
template: 'invitation-reminder-2'
}
];
async function scheduleReminders(invitation: Invitation) {
for (const reminder of invitationReminders) {
await scheduleEmail({
sendAt: addDays(invitation.createdAt, reminder.daysAfter),
to: invitation.email,
subject: reminder.subject,
template: reminder.template,
data: { invitation },
cancelIf: [
{ condition: 'invitation_accepted' },
{ condition: 'invitation_cancelled' }
]
});
}
}
Invitations spécifiques au rôle
Invitation d’administrateur
await sendEmail({
to: invitee.email,
subject: `You've been invited as an admin of ${org.name}`,
template: 'admin-invitation',
data: {
inviter,
organization: org,
role: 'Admin',
permissions: [
'Manage team members',
'Access billing',
'Configure integrations',
'View all projects'
],
acceptUrl: `${baseUrl}/invitations/${invitation.id}/accept`
}
});
Invitation pour rôle limité
await sendEmail({
to: invitee.email,
subject: `${inviter.name} invited you to collaborate on ${org.name}`,
template: 'member-invitation',
data: {
inviter,
organization: org,
role: 'Member',
accessScope: 'You\'ll have access to projects you\'re added to',
acceptUrl: `${baseUrl}/invitations/${invitation.id}/accept`
}
});
Parcours après acceptation
Bienvenue dans l’équipe
// After invitation accepted
await sendEmail({
to: newMember.email,
subject: `Welcome to ${org.name}!`,
template: 'team-welcome',
data: {
member: newMember,
organization: org,
invitedBy: inviter,
gettingStarted: [
{ step: 'Complete your profile', url: `${baseUrl}/settings/profile` },
{ step: 'Explore your projects', url: `${baseUrl}/projects` },
{ step: 'Meet your team', url: `${baseUrl}/team` }
],
helpResources: {
docs: `${baseUrl}/docs`,
support: `${baseUrl}/support`
}
}
});
Notifier l’invitant
await sendEmail({
to: inviter.email,
subject: `${invitee.name} joined ${org.name}`,
template: 'invitation-accepted',
data: {
inviter,
newMember: {
name: invitee.name,
email: invitee.email,
role: invitee.role
},
teamUrl: `${baseUrl}/team`
}
});
Gestion des cas particuliers
Invitation d’un utilisateur existant
if (await userExists(invitee.email)) {
await sendEmail({
to: invitee.email,
subject: `${inviter.name} invited you to join ${org.name}`,
template: 'existing-user-invitation',
data: {
inviter,
organization: org,
// Different CTA - just accept, no signup
acceptUrl: `${baseUrl}/invitations/${invitation.id}/accept`,
note: 'You already have an account. Just click to join.'
}
});
}
Invitation envoyée au mauvais email
// Allow forwarding to correct email
await sendEmail({
to: invitee.email,
template: 'invitation',
data: {
// ...
wrongEmailUrl: `${baseUrl}/invitations/${invitation.id}/wrong-email`,
wrongEmailNote: 'Not the right email? Let us know.'
}
});
Bonnes pratiques
- —Contexte clair de l’expéditeur - Qui les a invités et pourquoi
- —Montrez l’équipe - La preuve sociale augmente l’acceptation
- —Expliquez le rôle - À quoi ils auront accès
- —CTA simple - Un bouton pour accepter
- —Rappelez avec douceur - 2 à 3 relances maximum
- —Refus facile - Permettez-leur de refuser en toute simplicité
- —Accueillez chaleureusement - Excellente première impression après acceptation
Les invitations d’équipe sont souvent la première interaction de quelqu’un avec votre produit. Faites en sorte qu’elle compte.