← Retour aux articles
Tooling PostHogAnalyticsTypeScript

PostHog : des analytics produit que les développeurs contrôlent vraiment

· 8 min de lecture

Google Analytics dit combien de personnes ont visité votre page marketing. Il ne dit pas pourquoi les utilisateurs abandonnent votre onboarding à l’étape 3, quelle feature drive la rétention, ou si le nouveau design du checkout convertit réellement mieux. PostHog est construit pour ce niveau d’insight produit. Il combine le tracking d’événements, les funnels, les session replays, les feature flags et l’A/B testing dans une seule plateforme que les développeurs intègrent directement dans la codebase. Pas de tag managers, pas de scripts tiers injectés par le marketing, pas de boîte noire entre votre code et vos données.

Tracking d’événements : capturer ce qui compte

PostHog capture des événements. Chaque clic de bouton, page vue, soumission de formulaire ou appel API peut devenir un événement tracké avec des propriétés structurées. Le SDK est léger et fonctionne avec React, Next.js, Node.js et toutes les plateformes majeures.

import posthog from 'posthog-js';

posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
  api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
  capture_pageview: false,
});

export default posthog;
import posthog from '@/lib/posthog';

function PricingCard({ plan }: { plan: Plan }) {
  function handleSubscribe() {
    posthog.capture('subscription_started', {
      plan: plan.name,
      price: plan.price,
      billing_cycle: plan.interval,
    });
  }

  return <button onClick={handleSubscribe}>S'abonner à {plan.name}</button>;
}

Mettre capture_pageview: false désactive le tracking automatique des pages vues, ce qui est le bon défaut pour les SPAs où la navigation ne déclenche pas de chargement de page complet. On gère les pages vues manuellement avec le router Next.js ou un composant layout, ce qui donne le contrôle sur ce qui compte comme page vue.

Les propriétés d’événements sont là où réside la vraie valeur. Tracker “subscription_started” seul dit combien de gens s’abonnent. Ajouter plan, price et billing_cycle permet de répondre à quel plan convertit le mieux, si la facturation annuelle surpasse le mensuel, et comment les changements de prix affectent la conversion dans le temps.

Identifier les utilisateurs entre les sessions

Les événements anonymes sont utiles pour les tendances agrégées, mais les analytics produit deviennent puissantes quand les événements sont liés à des utilisateurs spécifiques. posthog.identify relie tous les événements passés et futurs à une identité utilisateur.

import { useEffect } from 'react';
import posthog from '@/lib/posthog';

export function usePostHogIdentity(user: User | null) {
  useEffect(() => {
    if (user) {
      posthog.identify(user.id, {
        email: user.email,
        name: user.name,
        plan: user.plan,
        created_at: user.createdAt,
      });
    } else {
      posthog.reset();
    }
  }, [user]);
}

Le second argument définit des propriétés utilisateur qui persistent entre les sessions. Quand l’utilisateur se déconnecte, posthog.reset() efface l’identité et démarre une nouvelle session anonyme. Ça empêche les événements d’un utilisateur de contaminer ceux d’un autre sur les appareils partagés.

Les propriétés utilisateur enrichissent chaque analyse. Au lieu de “500 personnes ont cliqué sur le bouton export,” on peut filtrer par plan, date d’inscription ou n’importe quelle propriété custom pour trouver les patterns qui comptent.

Funnels : trouver où les utilisateurs décrochent

Un funnel suit une séquence d’événements et montre où les utilisateurs abandonnent le parcours. Complétion de l’onboarding, conversion du checkout, adoption d’une feature, tout processus multi-étapes peut être mesuré.

// Étape 1 : l'utilisateur arrive sur l'onboarding
posthog.capture('onboarding_started');

// Étape 2 : l'utilisateur complète son profil
posthog.capture('profile_completed', {
  fields_filled: ['name', 'company', 'role'],
});

// Étape 3 : l'utilisateur crée son premier projet
posthog.capture('first_project_created', {
  template_used: 'blank',
});

// Étape 4 : l'utilisateur invite un membre d'équipe
posthog.capture('team_member_invited');

Dans le dashboard PostHog, on crée un funnel avec ces quatre événements dans l’ordre. PostHog montre le taux de conversion entre chaque étape, le temps médian entre les étapes, et quels segments d’utilisateurs convertissent le mieux. Si 70% des utilisateurs complètent leur profil mais seulement 30% créent un projet, le problème est clair et spécifique.

Les funnels supportent aussi le breakdown par propriété. On peut découvrir que les utilisateurs qui choisissent un template convertissent à 60% tandis que ceux qui partent d’un projet vierge convertissent à 20%. C’est une décision produit basée sur des données, pas de l’intuition.

Feature flags : livrer en toute sécurité

Les feature flags permettent d’activer des fonctionnalités pour des utilisateurs spécifiques, des pourcentages ou des conditions sans déployer de nouveau code. Les flags de PostHog sont évalués côté serveur ou client avec une latence quasi nulle.

import { useFeatureFlagEnabled } from 'posthog-js/react';

function Dashboard() {
  const showNewDashboard = useFeatureFlagEnabled('new-dashboard-v2');

  return showNewDashboard ? <NewDashboard /> : <LegacyDashboard />;
}
import { PostHog } from 'posthog-node';

const posthog = new PostHog(process.env.POSTHOG_API_KEY!);

export async function getFeatureFlag(userId: string, flag: string) {
  return posthog.isFeatureEnabled(flag, userId);
}

Les flags fonctionnent côté client avec le hook React et côté serveur avec le SDK Node.js. Un déploiement typique démarre à 10% des utilisateurs, surveille les taux d’erreur et les métriques clés, puis monte graduellement à 100%. Si quelque chose casse, on désactive le flag instantanément sans déploiement de rollback.

PostHog lie les feature flags aux analytics automatiquement. Quand un flag est actif, chaque événement de cet utilisateur est tagué avec l’état du flag. On peut comparer les taux de conversion, d’erreur et d’engagement entre les groupes flag-on et flag-off sans instrumentation supplémentaire.

A/B testing : mesurer l’impact

Les A/B tests s’appuient sur les feature flags en ajoutant de la rigueur statistique. On définit une hypothèse, on sépare les utilisateurs en groupes contrôle et variant, et PostHog calcule si la différence sur une métrique cible est statistiquement significative.

import { useFeatureFlagVariantKey } from 'posthog-js/react';

function CTAButton() {
  const variant = useFeatureFlagVariantKey('cta-experiment');

  const label = variant === 'test' ? 'Start free trial' : 'Get started';
  const color = variant === 'test' ? 'bg-green-600' : 'bg-blue-600';

  return (
    <button className={color} onClick={() => posthog.capture('cta_clicked', { variant })}>
      {label}
    </button>
  );
}

PostHog gère la randomisation et garantit que chaque utilisateur voit toujours le même variant. Le dashboard d’expérimentation montre les taux de conversion pour chaque variant, les intervalles de confiance, et si le résultat est significatif. Pas de tableurs, pas de calculs manuels, pas de devinette sur quand arrêter le test.

Session replays : voir ce qui s’est passé

Les session replays enregistrent les interactions utilisateur et permettent de regarder exactement ce qui s’est passé pendant une session. Clics, scrolls, saisies de formulaire, navigation, rage clicks, tout est capturé et rejoué dans le dashboard PostHog.

posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY!, {
  api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
  capture_pageview: false,
  session_recording: {
    maskAllInputs: true,
    maskTextSelector: '[data-sensitive]',
  },
});

maskAllInputs remplace les valeurs des inputs par des astérisques dans les enregistrements, empêchant la capture de données sensibles comme les mots de passe et numéros de carte. maskTextSelector permet de masquer des éléments spécifiques par sélecteur.

La vraie puissance est de lier les replays aux analytics. Quand un funnel montre 40% de drop à l’étape 3, on peut cliquer pour voir les session replays des utilisateurs qui ont décroché et regarder ce qui s’est réellement passé. Peut-être que le bouton de soumission était sous le fold. Peut-être qu’un toast d’erreur est apparu et a disparu trop vite. Le replay supprime la spéculation.

Tracking serveur avec Node.js

Le tracking côté client couvre les interactions UI. Le tracking côté serveur couvre les événements métier qui ne devraient pas dépendre du navigateur : paiements traités, emails envoyés, jobs de fond terminés.

import { PostHog } from 'posthog-node';

const posthog = new PostHog(process.env.POSTHOG_API_KEY!, {
  host: process.env.POSTHOG_HOST,
});

export async function processPayment(userId: string, amount: number) {
  const result = await stripe.charges.create({ amount, currency: 'eur' });

  posthog.capture({
    distinctId: userId,
    event: 'payment_processed',
    properties: {
      amount,
      currency: 'eur',
      payment_id: result.id,
      status: result.status,
    },
  });

  return result;
}

Les événements côté serveur sont plus fiables que côté client. Ils ne peuvent pas être bloqués par les ad blockers, perdus à cause de problèmes réseau, ou sautés quand les utilisateurs ferment l’onglet. Pour les événements critiques comme les paiements, le tracking côté serveur est la seule approche qui donne des chiffres précis.

Self-hosting : posséder ses données

PostHog peut tourner entièrement sur votre propre infrastructure. Aucune donnée ne quitte vos serveurs. Aucun tiers n’a accès au comportement de vos utilisateurs. C’est important pour la conformité RGPD, les clients entreprise avec des exigences de résidence des données, et les équipes qui ne veulent simplement pas de leurs données produit dans le cloud de quelqu’un d’autre.

services:
  posthog:
    image: posthog/posthog:latest
    environment:
      - SECRET_KEY=your-secret-key
      - DATABASE_URL=postgres://posthog:posthog@db:5432/posthog
      - REDIS_URL=redis://redis:6379
    ports:
      - '8000:8000'
    depends_on:
      - db
      - redis

  db:
    image: postgres:16-alpine

  redis:
    image: redis:7-alpine

La version self-hosted a les mêmes fonctionnalités que la version cloud. Ingestion d’événements, dashboards, funnels, feature flags, session replays, tout tourne sur une infrastructure qu’on contrôle. Les mises à jour sont tirées comme des versions d’images Docker, et le chemin de migration entre self-hosted et cloud est simple.

Conclusion

PostHog met les analytics produit dans la codebase, là où elles ont leur place. Les événements sont trackés dans les mêmes fonctions qui gèrent la logique métier. Les feature flags vivent à côté des composants qu’ils contrôlent. Le tracking côté serveur garantit que les événements critiques ne sont jamais perdus. Et le self-hosting signifie que vos données restent les vôtres. Pour tout produit qui a besoin de comprendre le comportement utilisateur au-delà des pages vues et des taux de rebond, PostHog remplace une pile entière d’outils déconnectés par une seule plateforme que les développeurs peuvent vraiment posséder.