Exemple complet
Page HTML de test avec le widget Saasy et des éléments ciblés pour configurer tes flows d'onboarding.
Exemple complet
Cette page fournit une application HTML de test que tu peux héberger localement ou sur CodePen. Elle charge le vrai widget Saasy et expose des éléments ciblés avec des sélecteurs CSS précis. Tu configures ensuite tes flows dans le Canvas Builder du dashboard en pointant sur ces sélecteurs.
Comment utiliser cet exemple
- Copie le code HTML ci-dessous dans un fichier
index.htmlou dans CodePen - Remplace
app_ton_app_keypar ta clé d'intégration (disponible dans Onboarding > Paramètres) - Lance ton API Saasy en local (
npm run dev) ou pointe vers ton instance de production - Ouvre la page dans ton navigateur
- Dans le dashboard Saasy, crée un flow et utilise les sélecteurs CSS du tableau ci-dessous pour ancrer tes tooltips, modales, etc.
Sélecteurs CSS disponibles
Voici les éléments ciblés disponibles dans la page d'exemple. Utilise ces sélecteurs dans le Canvas Builder pour ancrer tes composants :
| Sélecteur CSS | Élément | Cas d'usage |
|---|---|---|
#create-project-btn | Bouton "Créer un projet" | Tooltip pour guider la création |
#user-avatar | Avatar utilisateur (header) | Tooltip profil |
#nav-dashboard | Lien nav "Dashboard" | Tooltip navigation |
#nav-projects | Lien nav "Projets" | Tooltip navigation |
#nav-analytics | Lien nav "Analytiques" | Tooltip navigation |
#nav-settings | Lien nav "Paramètres" | Tooltip navigation |
#stat-users | Carte stat "Utilisateurs" | Tooltip métriques |
#stat-revenue | Carte stat "Revenus" | Tooltip métriques |
#stat-conversion | Carte stat "Conversion" | Tooltip métriques |
#welcome-card | Carte de bienvenue | Tooltip ou spotlight |
#feature-analytics | Feature "Analytiques" | Tooltip fonctionnalités |
#feature-integrations | Feature "Intégrations" | Tooltip fonctionnalités |
#feature-team | Feature "Équipe" | Tooltip fonctionnalités |
#feature-export | Feature "Export" | Tooltip fonctionnalités |
#search-input | Champ de recherche | Tooltip recherche |
#upgrade-btn | Bouton "Passer en Pro" | Tooltip upgrade |
[data-onb="sidebar"] | Sidebar complète | Zone pour slideout |
[data-onb="main-content"] | Zone de contenu principal | Zone pour modale/bannière |
Code HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Mon App - Page de test Saasy Onboarding</title>
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: #f8fafc;
color: #1e293b;
min-height: 100vh;
display: flex;
}
/* ── Sidebar ────────────────────────────────────────────── */
.sidebar {
width: 240px;
background: #0f172a;
color: #94a3b8;
display: flex;
flex-direction: column;
min-height: 100vh;
position: fixed;
left: 0;
top: 0;
bottom: 0;
}
.sidebar .logo {
padding: 20px 20px 24px;
font-size: 18px;
font-weight: 700;
color: #fff;
letter-spacing: -0.02em;
}
.sidebar nav { flex: 1; padding: 0 12px; }
.sidebar nav a {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-radius: 8px;
font-size: 14px;
color: #94a3b8;
text-decoration: none;
transition: all 0.15s;
margin-bottom: 2px;
}
.sidebar nav a:hover { background: #1e293b; color: #e2e8f0; }
.sidebar nav a.active { background: #1e293b; color: #fff; }
.sidebar nav a .icon { font-size: 18px; width: 24px; text-align: center; }
.sidebar .sidebar-footer {
padding: 16px 20px;
border-top: 1px solid #1e293b;
}
.sidebar .sidebar-footer .upgrade-btn {
display: block;
width: 100%;
padding: 10px;
background: #2563eb;
color: #fff;
border: none;
border-radius: 8px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
text-align: center;
transition: background 0.15s;
}
.sidebar .sidebar-footer .upgrade-btn:hover { background: #1d4ed8; }
/* ── Main ───────────────────────────────────────────────── */
.main { margin-left: 240px; flex: 1; min-height: 100vh; }
.topbar {
background: #fff;
border-bottom: 1px solid #e2e8f0;
padding: 0 24px;
height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
top: 0;
z-index: 10;
}
.topbar .search {
display: flex;
align-items: center;
gap: 8px;
background: #f1f5f9;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 8px 14px;
width: 320px;
}
.topbar .search input {
border: none;
background: none;
outline: none;
font-size: 14px;
color: #334155;
width: 100%;
font-family: inherit;
}
.topbar .search input::placeholder { color: #94a3b8; }
.topbar .search .icon { color: #94a3b8; }
.topbar .user-area {
display: flex;
align-items: center;
gap: 12px;
}
.topbar .notif-btn {
position: relative;
background: none;
border: none;
cursor: pointer;
font-size: 20px;
color: #64748b;
padding: 6px;
border-radius: 8px;
transition: background 0.15s;
}
.topbar .notif-btn:hover { background: #f1f5f9; }
.topbar .notif-btn .badge {
position: absolute;
top: 2px;
right: 2px;
width: 8px;
height: 8px;
background: #ef4444;
border-radius: 50%;
}
.avatar {
width: 36px;
height: 36px;
border-radius: 50%;
background: #3b82f6;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
/* ── Content ────────────────────────────────────────────── */
.content { padding: 24px; max-width: 1024px; }
.page-header {
margin-bottom: 24px;
}
.page-header h1 { font-size: 22px; font-weight: 700; color: #0f172a; }
.page-header p { font-size: 14px; color: #64748b; margin-top: 4px; }
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
margin-bottom: 24px;
}
.stat-card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 20px;
}
.stat-card .label {
font-size: 12px;
color: #94a3b8;
text-transform: uppercase;
letter-spacing: 0.05em;
font-weight: 500;
}
.stat-card .value {
font-size: 28px;
font-weight: 700;
color: #0f172a;
margin-top: 4px;
}
.stat-card .change {
font-size: 12px;
margin-top: 4px;
font-weight: 500;
}
.stat-card .change.up { color: #16a34a; }
.stat-card .change.down { color: #dc2626; }
.card {
background: #fff;
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 24px;
margin-bottom: 20px;
}
.card h2 { font-size: 16px; font-weight: 600; margin-bottom: 8px; }
.card p { font-size: 14px; color: #64748b; line-height: 1.6; }
.btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 10px 18px;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
border: none;
cursor: pointer;
transition: all 0.15s;
font-family: inherit;
}
.btn-primary { background: #2563eb; color: #fff; }
.btn-primary:hover { background: #1d4ed8; }
.btn-secondary { background: #f1f5f9; color: #334155; border: 1px solid #e2e8f0; }
.btn-secondary:hover { background: #e2e8f0; }
.feature-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
}
.feature-item {
background: #fff;
padding: 20px;
border: 1px solid #e2e8f0;
border-radius: 12px;
text-align: center;
cursor: pointer;
transition: all 0.15s;
}
.feature-item:hover { border-color: #3b82f6; box-shadow: 0 0 0 1px #3b82f6; }
.feature-item .icon { font-size: 32px; margin-bottom: 10px; }
.feature-item .name { font-size: 14px; font-weight: 600; }
.feature-item .desc { font-size: 12px; color: #94a3b8; margin-top: 6px; line-height: 1.4; }
.section-title {
font-size: 15px;
font-weight: 600;
margin-bottom: 16px;
color: #0f172a;
}
/* ── Event log ──────────────────────────────────────────── */
.event-log {
position: fixed;
bottom: 0;
left: 240px;
right: 0;
background: #1e293b;
border-top: 2px solid #3b82f6;
padding: 10px 16px;
z-index: 100;
}
.event-log h4 {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #64748b;
margin-bottom: 6px;
}
.event-log .log-content {
font-family: 'SF Mono', Monaco, monospace;
font-size: 11px;
color: #94a3b8;
max-height: 60px;
overflow-y: auto;
line-height: 1.6;
}
.event-log .log-content .entry { color: #22d3ee; }
</style>
</head>
<body>
<!-- ══════════════════════════════════════════════════════════ -->
<!-- Sidebar -->
<!-- ══════════════════════════════════════════════════════════ -->
<aside class="sidebar" data-onb="sidebar">
<div class="logo">MonApp</div>
<nav>
<a href="#" class="active" id="nav-dashboard">
<span class="icon">■</span> Dashboard
</a>
<a href="#" id="nav-projects">
<span class="icon">☰</span> Projets
</a>
<a href="#" id="nav-analytics">
<span class="icon">●</span> Analytiques
</a>
<a href="#" id="nav-settings">
<span class="icon">⚙</span> Paramètres
</a>
</nav>
<div class="sidebar-footer">
<button class="upgrade-btn" id="upgrade-btn">Passer en Pro</button>
</div>
</aside>
<!-- ══════════════════════════════════════════════════════════ -->
<!-- Main content -->
<!-- ══════════════════════════════════════════════════════════ -->
<div class="main">
<header class="topbar">
<div class="search" id="search-input">
<span class="icon">🔍</span>
<input type="text" placeholder="Rechercher..." />
</div>
<div class="user-area">
<button class="notif-btn" id="notif-btn">
🔔<span class="badge"></span>
</button>
<div class="avatar" id="user-avatar">AM</div>
</div>
</header>
<div class="content" data-onb="main-content">
<div class="page-header">
<h1>Dashboard</h1>
<p>Vue d'ensemble de ton activité</p>
</div>
<!-- Stats -->
<div class="stats-grid">
<div class="stat-card" id="stat-users">
<div class="label">Utilisateurs</div>
<div class="value">1 248</div>
<div class="change up">+12% ce mois</div>
</div>
<div class="stat-card" id="stat-revenue">
<div class="label">Revenus</div>
<div class="value">8 420 €</div>
<div class="change up">+8% ce mois</div>
</div>
<div class="stat-card" id="stat-conversion">
<div class="label">Conversion</div>
<div class="value">3.2%</div>
<div class="change down">-0.4% ce mois</div>
</div>
</div>
<!-- Welcome card -->
<div class="card" id="welcome-card">
<h2>Bienvenue dans ton espace</h2>
<p>
Commence par créer ton premier projet pour découvrir toutes les
fonctionnalités de la plateforme. Tu peux aussi explorer les
sections ci-dessous.
</p>
<button class="btn btn-primary" id="create-project-btn" style="margin-top: 14px;">
Créer un projet
</button>
</div>
<!-- Features -->
<div class="section-title">Fonctionnalités</div>
<div class="feature-grid">
<div class="feature-item" id="feature-analytics">
<div class="icon">📊</div>
<div class="name">Analytiques</div>
<div class="desc">Suis tes métriques en temps réel</div>
</div>
<div class="feature-item" id="feature-integrations">
<div class="icon">🔗</div>
<div class="name">Intégrations</div>
<div class="desc">Connecte tes outils préférés</div>
</div>
<div class="feature-item" id="feature-team">
<div class="icon">👥</div>
<div class="name">Équipe</div>
<div class="desc">Collabore avec ton équipe</div>
</div>
<div class="feature-item" id="feature-export">
<div class="icon">📤</div>
<div class="name">Export</div>
<div class="desc">Exporte tes données facilement</div>
</div>
</div>
</div>
</div>
<!-- ══════════════════════════════════════════════════════════ -->
<!-- Event log (affiche les événements onboarding en live) -->
<!-- ══════════════════════════════════════════════════════════ -->
<div class="event-log">
<h4>Événements Onboarding (live)</h4>
<div class="log-content" id="event-log">
En attente du widget...
</div>
</div>
<!-- ══════════════════════════════════════════════════════════ -->
<!-- Saasy Widget — remplace app_ton_app_key par ta vraie clé -->
<!-- ══════════════════════════════════════════════════════════ -->
<script>
window.SaasyConfig = {
appKey: "app_ton_app_key",
// En local : pointe vers ton API
// apiUrl: "http://localhost:3001",
};
</script>
<script src="https://cdn.saasy.fr/widget.js" async></script>
<script>
// ── Identification utilisateur ─────────────────────────
// Appel identify() pour que le ciblage fonctionne.
// Adapte les attributs à ton modèle utilisateur.
document.addEventListener("saasy:ready", function () {
window.Saasy.identify({
userId: "usr_demo_001",
email: "alice@exemple.fr",
name: "Alice Martin",
plan: "free",
createdAt: "2026-02-01",
sessionCount: 3,
featureUsagePercent: 20,
});
});
// ── Log des événements onboarding ──────────────────────
var logEl = document.getElementById("event-log");
function logEvent(name) {
return function (e) {
var detail = e.detail ? JSON.stringify(e.detail) : "";
var time = new Date().toLocaleTimeString();
logEl.innerHTML +=
'<div><span class="entry">[' + time + "] " + name + "</span> " +
detail + "</div>";
logEl.scrollTop = logEl.scrollHeight;
};
}
// Écoute tous les événements onboarding
var events = [
"saasy:onb:flow:started",
"saasy:onb:flow:completed",
"saasy:onb:flow:dismissed",
"saasy:onb:step:viewed",
"saasy:onb:step:completed",
"saasy:onb:step:dismissed",
"saasy:onb:step:cta_clicked",
"saasy:onb:checklist:viewed",
"saasy:onb:checklist:item_completed",
"saasy:onb:checklist:completed",
"saasy:onb:checklist:dismissed",
"saasy:onb:resource:viewed",
"saasy:onb:resource:clicked",
];
events.forEach(function (evt) {
document.addEventListener(evt, logEvent(evt));
});
// ── API manuelle (optionnel) ───────────────────────────
// Tu peux aussi déclencher un flow manuellement :
// window.Saasy.onboarding.startFlow("ton_flow_id");
</script>
</body>
</html>Idées de flows à configurer
Voici des parcours que tu peux créer dans le Canvas Builder en utilisant les sélecteurs ci-dessus. Chaque exemple combine plusieurs widgets pour illustrer les possibilités.
Flow "Bienvenue" — Modale + Tooltips + Bannière
Un parcours d'accueil classique qui enchaîne modale, tooltips et bannière :
- Modale (layout
large) — Message de bienvenue avec titre "Bienvenue sur MonApp !" et contenu présentant les 3 fonctionnalités clés. Ajoute une image ou vidéo de démo en media. - Tooltip sur
#stat-users(placementbottom) — "Voici tes métriques. Tu peux suivre l'évolution de tes utilisateurs en temps réel." - Tooltip sur
#stat-revenue(placementbottom) — "Consulte l'évolution de tes revenus ici." - Tooltip sur
#create-project-btn(placementright) — "Crée ton premier projet pour commencer." Active le backdrop spotlight pour focaliser l'attention. - Bannière (position
top, couleur#16a34a) — "Tu as terminé le tour ! Besoin d'aide ? Consulte notre centre de ressources."
Flow "Tour sidebar" — Slideout + Tooltips
Présente la navigation latérale avec un slideout puis des tooltips :
- Slideout (position
right, largeurmd) — Panneau avec titre "Découvre la navigation" et contenu expliquant la structure de la sidebar : Dashboard, Projets, Analytiques, Paramètres. - Tooltip sur
#nav-dashboard(placementright) — "Le dashboard est ta page d'accueil." - Tooltip sur
#nav-projects(placementright) — "Gère tous tes projets ici." - Tooltip sur
#nav-analytics(placementright) — "Analyse tes métriques." - Tooltip sur
#nav-settings(placementright) — "Configure ton compte et tes préférences."
Flow "Découverte features" — Modale compact + Tooltips
Un parcours centré sur les fonctionnalités :
- Modale (layout
compact) — "Découvre nos fonctionnalités" avec un court texte d'introduction. - Tooltip sur
#feature-analytics(placementbottom) — "Suis tes métriques en temps réel avec des graphiques interactifs." - Tooltip sur
#feature-integrations(placementbottom) — "Connecte Slack, Zapier, et tes outils préférés." - Tooltip sur
#feature-team(placementbottom) — "Invite ton équipe et collabore en temps réel." - Tooltip sur
#feature-export(placementbottom) — "Exporte tes données en CSV, PDF ou via API."
Flow "Upgrade" — Bannière + Slideout + Tooltip
Un parcours de conversion pour les utilisateurs gratuits :
- Bannière (position
top, couleur#7c3aed) — "Profite de -20% sur le plan Pro cette semaine !" - Délai — Attendre 10 secondes avant de continuer (laisse l'utilisateur lire la bannière).
- Slideout (position
right, largeurlg) — Panneau "Passe en Pro" avec un comparatif des fonctionnalités Free vs Pro. Ajoute un bouton CTA "Découvrir le plan Pro" de typelink. - Tooltip sur
#upgrade-btn(placementtop) — "Clique ici pour activer ton plan Pro." Active le backdrop spotlight.
Utilise un segment "Plan gratuit" (condition : plan égal à free) pour cibler uniquement les utilisateurs qui n'ont pas encore fait l'upgrade.
Flow "Onboarding conditionnel" — Condition + Modale + Bannière
Un parcours qui s'adapte au profil de l'utilisateur :
- Condition — Attribut
sessionCount, opérateur "Supérieur à", valeur10.- Branche vraie : l'utilisateur est expérimenté, on passe à l'étape 2.
- Branche fausse : l'utilisateur est nouveau, on passe à l'étape 3.
- Bannière (position
bottom) — "Tu maîtrises MonApp ! Découvre nos fonctionnalités avancées." - Modale (layout
large) — "Bienvenue ! On va t'aider à prendre en main MonApp en quelques étapes."
Les branches conditionnelles se configurent dans le Canvas Builder en connectant les sorties "Vrai" et "Faux" du noeud Condition vers des noeuds différents.
Flow "Rappel après délai" — Délai + Bannière
Rappelle une action importante après un délai :
- Délai — Attendre 1 jour (l'utilisateur revient le lendemain).
- Modale (layout
compact) — "Content de te revoir ! Tu n'as pas encore créé de projet. C'est le moment de commencer." - Tooltip sur
#create-project-btn(placementright) — "Crée ton premier projet maintenant." Active le backdrop spotlight.
Flow "Bottom sheet mobile" — Modale bottom-sheet + Tooltip
Un parcours optimisé pour les utilisateurs mobiles :
- Modale (layout
bottom-sheet) — "Bienvenue sur MonApp !" avec un texte court et un bouton "C'est parti". Le bottom-sheet s'affiche depuis le bas de l'écran, idéal pour le mobile. - Tooltip sur
#search-input(placementbottom) — "Utilise la recherche pour trouver rapidement ce que tu cherches." - Bannière (position
bottom, couleur#0ea5e9) — "Astuce : tu peux utiliser le raccourci Cmd+K pour ouvrir la recherche."
Checklist "Pour bien démarrer"
Crée une checklist avec le mode d'affichage flottant (ou sidebar pour la garder toujours visible) :
| Item | Description | Type CTA | Cible |
|---|---|---|---|
| Configurer ton profil | Complète tes informations | link | #user-avatar |
| Créer un projet | Lance ton premier projet | link | #create-project-btn |
| Explorer les analytiques | Découvre tes métriques | link | #nav-analytics |
| Inviter un coéquipier | Collabore avec ton équipe | link | #feature-team |
| Passer en Pro | Débloque toutes les fonctionnalités | link | #upgrade-btn |
Active la barre de progression et rends la checklist dismissible.
Checklist "Setup technique"
Un exemple de checklist en mode sidebar pour les développeurs :
| Item | Description | Type CTA | Cible |
|---|---|---|---|
| Ajouter le widget | Intègre le script dans ton app | link | URL vers la doc d'installation |
| Configurer l'API key | Génère ta clé dans les paramètres | link | #nav-settings |
| Identifier les utilisateurs | Appelle Saasy.identify() | event | open-docs |
| Créer ton premier flow | Lance le Canvas Builder | flow | ID du flow de bienvenue |
Le type CTA flow permet de déclencher un autre flow d'onboarding directement depuis un item de la checklist. Utilise-le pour chaîner des parcours.
Attributs utilisateur pour le ciblage
L'appel Saasy.identify() dans l'exemple envoie ces attributs que tu peux utiliser dans les segments :
| Attribut | Valeur | Utilisation |
|---|---|---|
plan | "free" | Segment "Plan gratuit" |
createdAt | "2026-02-01" | Segment "Nouveaux utilisateurs" |
sessionCount | 3 | Segment "Utilisateurs débutants" (< 5 sessions) |
featureUsagePercent | 20 | Segment "Découverte features" (< 50%) |
Change ces valeurs pour tester différents segments.