Je conçois et maintiens les nombreux workflows n8n de mes clients. Les expressions n8n sont mon accélérateur principal : elles me permettent de paramétrer finement les nœuds, de nettoyer la donnée « à la voléeé, d’éviter des nœuds “Code” quand ce n’est pas nécessaire, et de rendre un workflow lisible. Mon objectif ici est double : vous donner un savoir opératoire (quoi écrire, où, pourquoi) et une méthode (comment rester lisible, testable et stable).
Objectif clair de Franck le formateur n8n : à la fin, vous saurez quoi écrire entre {{ ... }}, où l’écrire, comment accéder à vos données, comment formater proprement, comment gérer les dates avec Luxon, comment requêter du JSON avec $jmespath(), comment déboguer et comment rester lisible. Le tout avec des exemples complets et reproductibles.
Qu’est-ce que les expressions n8n ? (guide, aide)
Définition simple. Une expression n8n est un petit morceau de JavaScript écrit entre {{ et }}. n8n évalue ce code et remplace l’expression par sa valeur. Vous pouvez :
- lire les données de l’item courant avec
$json, - lire des fichiers ou méta avec
$binary, - accéder à la sortie d’un autre nœud avec
$("NomDuNœud"), - manipuler dates/temps avec Luxon via
$nowet$today, - interroger du JSON avec JMESPath via
$jmespath(obj, requête).
Où peut-on écrire une expression ? Dans la majorité des champs des nœuds (Set, HTTP Request, If, etc.). Dans l’UI, cliquez sur l’icône “Expression” à droite du champ pour passer en mode expression.
Exemple minimal.
Entrée (item courant) :
{ "email": "alice@example.com", "id": 42 }Expression dans un champ :
🚀 Agents IA n8n : une formation pratique pour accélerer votre productivité avec le No Code !
Les formations n8n vous ouvrent les portes d’une automatisation intelligente, fluide et évolutive. Vous y apprendrez à construire des workflows sur mesure, à interconnecter vos outils métiers, à transformer vos données, et même à intégrer des agents IA ou des systèmes RAG dans vos scénarios. Grâce à une approche progressive et concrète, vous gagnez en clarté, en efficacité, et en autonomie pour faire de n8n un véritable levier de productivité dans vos projets.
{{$json.email}}Sortie dans ce champ :
alice@example.comOù écrire des expressions n8n et comment s’assurer que ça marche ? (tuto)
- Ouvrez un nœud (ex. Set).
- Dans un champ, cliquez sur l’icône “Expression”.
- Tapez
{{$json}}pour visualiser l’objet courant. - Remplacez ensuite par la propriété voulue :
{{$json.email}}. - Vérifiez l’aperçu (n8n montre la valeur résolue sous le champ).
- Exécutez le nœud pour confirmer le résultat.
Astuce : “Pin data” sur les nœuds amont pour geler un jeu de test et stabiliser vos essais.
Quelles variables et méthodes existent en expressions n8n ? (support, aide)
| Élément | À quoi ça sert | Exemple d’usage |
|---|---|---|
$json | Données JSON de l’item courant | {{$json.user?.email}} |
$binary | Métadonnées/fichiers du courant | {{$binary.data.fileName}} |
$itemIndex | Index 0-based de l’item courant | {{"row_"+$itemIndex}} |
$input.all() | Tous les items entrants du nœud | {{$input.all().length}} |
$execution.id | Identifiant d’exécution | {{$execution.id}} |
$vars | Variables globales (config) | {{$vars.apiKey}} |
$("Nœud") | Accéder à un autre nœud | {{$("Lookup").first().json.id}} |
$now, $today | Date/heure (Luxon) | {{$now.toISO()}} |
$jmespath(obj,q) | Requêter un JSON (JMESPath) | {{$jmespath($json,"orders[?paid==true].id")}} |
Mini-exercice. Dans un nœud Set :
user_id = {{$("Fetch User").first().json.id}}full_name = {{[$json.first,$json.last].filter(Boolean).join(" ")}}created_iso = {{$now.toISO()}}
Comment accéder aux données d’autres nœuds avec les expressions n8n ? (guide)
Règle pratique :
$("Nom").first()quand le nœud renvoie un seul item logique.$("Nom").last()quand le nœud s’exécute plusieurs fois et vous voulez la dernière exécution.$("Nom").all()pour récupérer tous les items et les transformer (map/flatMap).
Exemple. Deux requêtes paginées “Page1” et “Page2” produisent :
// Page1: items
[{ "id": 1 }, { "id": 2 }]
// Page2: items
[{ "id": 3 }]Expression pour agréger tous les id :
{{ $("Page1").all().concat($("Page2").all()).flatMap(i => i.json || i.json?.items || [i.json]).map(x => x.id) }}Sortie :
[1,2,3]Astuce : renommez vos nœuds avec des noms stables et explicites. Vérifiez la correspondance d’item dans le panneau de mapping.
Comment écrire des expressions n8n sûres et robustes ? (aide)
Trois réflexes :
- Existence : utilisez l’optional chaining
?.{{$json?.user?.email}} - Valeur par défaut : utilisez
??si0ou""sont des valeurs acceptables{{$json.count ?? 0}} - Normalisation des tableaux/chaînes
{{ (Array.isArray($json.tags) ? $json.tags : [$json.tags]).filter(Boolean) }}
Anti-patrons fréquents : indexer [0] sans tester la longueur, confondre || et ??, mélanger Date natif et Luxon.
Comment manipuler des chaînes avec les expressions n8n ? (tuto, comment)
Slug robuste (accents, espaces, ponctuation) :
{{$json.title
.normalize('NFD').replace(/[\u0300-\u036f]/g,'')
.toLowerCase()
.replace(/[^a-z0-9\s-]/g,'')
.trim()
.replace(/\s+/g,'-')
}}Domaine d’email :
{{$json.email?.split("@")?.[1] ?? ""}}Nettoyage HTML → texte :
{{$json.html.replace(/<[^>]*>/g,' ').replace(/\s+/g,' ').trim()}}
Troncature propre 140 caractères :
{{ ($json.text||"").replace(/\s+/g," ").trim().slice(0,140) +
(($json.text||"").length>140 ? "…" : "") }}
Comment travailler tableaux et objets en expressions n8n ? (guide)
Pensez pipeline : map → filter → reduce → sort → join.
Liste de noms :
{{$json.users.map(u => [u.first,u.last].filter(Boolean).join(" ")).join(", ")}}Valeurs uniques :
{{[...new Set($json.tags || [])].join(",")}}Somme sécurisée :
{{$json.items.reduce((s,x) => s + (Number(x.price) || 0), 0)}}Rendu “clé: valeur” d’un objet :
{{Object.entries($json.config).map(([k,v]) => `${k}: ${v}`).join('\n')}}Comment gérer les dates avec les expressions n8n et Luxon ? (tuto détaillé, comment)
Pourquoi Luxon ici ?
Dans les expressions, n8n expose Luxon via deux objets prêts à l’emploi :
$now: date/heure du moment (Luxon DateTime)$today: minuit du jour (Luxon DateTime)
Bonnes pratiques :
- Rester full-Luxon dans une même expression.
- Définir la zone tôt (ex. “Europe/Paris”) avec
setZone(). - Calculer en DateTime, formater seulement à la fin avec
toISO()outoFormat().
Recettes Luxon prêtes à l’emploi
ISO immédiat :
{{$now.toISO()}}Demain 18:00 Europe/Paris :
{{$today.setZone("Europe/Paris").plus({days:1}).set({hour:18}).toISO()}}Fin du mois (date ISO) :
{{$now.endOf("month").toISODate()}}J+7 à 09:00 Europe/Paris :
{{$now.setZone("Europe/Paris").plus({days:7}).set({hour:9,minute:0}).toFormat("yyyy-LL-dd HH:mm")}}Fenêtre semaine locale (lundi → dimanche) :
{{(() => {
const zone = "Europe/Paris";
const start = $today.setZone(zone).startOf("week").plus({days:1}); // lundi
const end = start.plus({days:6}).endOf("day");
return { start: start.toISO(), end: end.toISO() };
})()}}Test “timestamp appartient à la semaine courante” :
{{(() => {
const zone = "Europe/Paris";
const ts = $json.timestamp; // ISO
if (!ts) return false;
const nowZ = $now.setZone(zone);
const w0 = nowZ.startOf("week").plus({days:1}); // lundi
const w1 = w0.plus({days:6}).endOf("day");
const x = DateTime.fromISO(ts).setZone(zone);
return x >= w0 && x <= w1;
})()}}Pièges fréquents, solutions claires
- Mélange Date natif et Luxon : restez sur Luxon dans l’expression.
- Faux fuseau : appliquez
setZone()tôt, gardez-le jusqu’au formatage. - Chaîne ambiguë : parsez explicitement (via
DateTime.fromISO(...)) dans une IIFE si nécessaire.
Exercices (dates)
deadline_iso= demain 18:00 “Europe/Paris”.- Objet
{start,end}pour le mois courant au format ISO local. - IIFE : parse
YYYY-MM-DDdepuis$json.date_simple, sortir ISO local à 09:00.
Comment requêter un JSON avec $jmespath() dans les expressions n8n ? (guide détaillé)
Pourquoi $jmespath() ?
JMESPath est un mini-langage déclaratif pour interroger un JSON. En une ligne, vous filtrez et projetez des structures profondes que JS natif exigerait d’écrire en plusieurs étapes.
Syntaxe utile (mémo)
- Propriété :
a.b - Projection tableau :
items[].id - Filtre :
items[?status=='paid'] - Filtre + projection :
items[?active==\true`].name` - Projection d’objets :
items[].{id:id,total:total} - Chaînage avec pipes : possible, améliore la lisibilité
- Booléens littéraux : backticks `true`, `false`
Recettes JMESPath directement utilisables
IDs des commandes payées :
{{$jmespath($json,"orders[?status=='paid'].id")}}Nom + score projetés, puis formatés côté JS :
{{$jmespath($json,"results[].{n:name,s:score}")
.map(x => `${x.n}: ${x.s}`)
.join("\n")
}}Aplatir tous les tags sur l’ensemble des items entrants :
{{[...new Set($jmespath($input.all(),"[].json.tags[]"))]}}Filtre multi-critères :
{{$jmespath($json,"results[?active==`true` && score>=`70`].name")}}Sélection d’objets avec renommage de clés :
{{$jmespath($json,"users[?role=='admin'].{id:id,mail:email}")}}Quand choisir JMESPath et quand rester en JS natif ?
- Choisissez JMESPath pour filtrer/projeter lisiblement des structures profondes.
- Revenez en JS natif pour des calculs/tri personnalisés ou des agrégations complexes après la projection.
Exercices (JMESPath)
users[?active==true].emailpuis tri alphabétique côté JS.- À partir de
{name, metrics:{score}}, projetez[{n:name,s:metrics.score}], puis moyenne côté JS. - Gardez
namedesresultsoùstatus=="ok"etscore>=70, puis joignez par", ".
Comment paramétrer des APIs avec les expressions n8n ? (tuto, support)
Travailler en objets JS et sérialiser à la fin rend tout plus stable.
Endpoint dynamique :
{{ `${$("CONFIG").first().json.baseUrl}/users/${$json.id}?q=${encodeURIComponent($json.q||"")}` }}En-têtes optionnels (filtrer les champs vides) :
{{ Object.fromEntries(
Object.entries($("CONFIG").first().json.headers)
.filter(([k,v]) => v != null)
)
}}Payload JSON propre :
{{ JSON.stringify({
id: $json.id,
when: $now.toISO(),
tags: ($json.tags || []).filter(Boolean)
})
}}Exercice. Reprenez un body écrit “en dur”, construisez l’objet en expression, supprimez les champs null/undefined avec Object.entries(...).filter(...), puis JSON.stringify(...).
Snippets réutilisables d’expressions n8n (support rapide)
- Nom complet :
{{[$json.first,$json.last].filter(Boolean).join(" ")}}- Valeurs uniques :
{{[...new Set($json.tags || [])].join(",")}}- Somme sécurisée :
{{$json.items.reduce((s,x) => s + (Number(x.price) || 0), 0)}}- Top 1 par prix :
{{$json.products.sort((a,b)=>b.price-a.price)[0]}}- CSV rapide :
{{(() => {
const rows = $json.rows || [];
const cols = ["id","name","email","created"];
const header = cols.join(",");
const body = rows.map(r => cols.map(c => {
const v = r[c] ?? "";
return `"${String(v).replace(/"/g,'""')}"`;
}).join(",")).join("\n");
return header + "\n" + body;
})()}}Comment déboguer ses expressions n8n ? (aide)
Méthode simple :
- Pin data sur le nœud source.
- Remplacez l’expression par
{{$json}}et regardez la réalité des champs. - Construisez l’expression étape par étape (ajoutez
split, puismap, etc.). - Testez
$jmespath()seul avant de le combiner. - Vérifiez l’orthographe exacte des nœuds dans
$("NomExact")et les “linked items” dans le panneau de mapping.
Exercices pratiques sur les expressions n8n (tuto appliqué)
- Extraire le domaine d’un email (
split("@")[1]) avec fallback"". - Transformer un
titlebruité entitle_slugrobuste. - Construire
full_nameavecfilter(Boolean).join(" "). - Calculer la somme de
priceen forçantNumber()et défaut0. - Générer un nom de fichier daté via
$now.toFormat("yyyyLLdd_HHmm"). - Produire
deadline_isodemain 18:00 Europe/Paris. - Obtenir
users[?active==true].emailvia$jmespath()puis trier.sort(). - Comparer
a ?? beta || baveca=0eta="". - Écrire un body JSON propre avec
Object.entries(...).filter(...)+JSON.stringify. - Écrire une “progress bar” 0–10 avec une IIFE courte.
- Construire une URL avec plusieurs paramètres encodés et
pagepar défaut. - Remplacer une expression à 4 conditions par une IIFE de 8–12 lignes commentées.
- Projeter
results[].{n:name,s:score}(JMESPath), puis mise en forme JS. - Aplatir tous les
tagsdes items entrants et obtenir des uniques. - Générer une table “clé: valeur” depuis un objet config.
- Fenêtre hebdo
{start,end}en ISO local avecstartOf/endOf. - Vérifier les “linked items” d’un Merge (panneau de mapping).
- Uniformiser toutes les dates sortantes en ISO avant envoi API.
- Remplacer une regex longue par 2–3 opérations simples si possible.
- Créer un nœud Set | CONFIG et éliminer toutes les constantes magiques.
FAQ — expressions n8n
Qu’est-ce qu’une expression n8n et où puis-je l’utiliser ?
{{ ... }} évalué dans la majorité des champs des nœuds (Set, HTTP Request, If, etc.). Elle permet d’accéder aux données courantes ($json), à d’autres nœuds ($("NomDuNœud")), aux dates via Luxon ($now, $today) et de requêter du JSON avec $jmespath().Comment écrire la syntaxe de base des expressions n8n (tuto) ?
{{$json.email}}. n8n affiche l’aperçu de la valeur évaluée sous le champ. Exemple d’URL dynamique : {{ `${$("CONFIG").first().json.baseUrl}/users/${$json.id}` }}.Quelles sont les variables intégrées utiles en expressions n8n (guide) ?
$json (item courant), $binary (fichiers), $itemIndex, $input.all(), $execution, $vars, accès inter-nœuds $("Nom").first()/last()/all(), dates $now/$today (Luxon) et $jmespath(obj, requête).Comment accéder aux données d’un autre nœud avec les expressions n8n (comment) ?
$("NomExactDuNœud"). Exemples : {{$("Lookup").first().json.id}} pour un unique item, {{$("HTTP Request").last().json}} pour la dernière exécution, {{$("Page1").all()}} pour agréger puis transformer via map/flatMap.Comment sécuriser mes expressions n8n contre les valeurs manquantes (aide) ?
?. ({{$json?.user?.email}}), valeur par défaut avec nullish coalescing ?? ({{$json.count ?? 0}}), et normalisation des tableaux : {{ (Array.isArray($json.tags)?$json.tags:[$json.tags]).filter(Boolean) }}.Comment manipuler des chaînes dans les expressions n8n (guide, tuto) ?
{{$json.title.normalize('NFD').replace(/[\u0300-\u036f]/g,'').toLowerCase().replace(/[^a-z0-9\s-]/g,'').trim().replace(/\s+/g,'-')}}Domaine d’email :
{{$json.email?.split("@")?.[1] ?? ""}}Nettoyage HTML :
{{$json.html.replace(/<[^>]*>/g,' ').replace(/\s+/g,' ').trim()}}Comment traiter les tableaux et objets avec les expressions n8n (support) ?
Liste de noms :
{{$json.users.map(u=>[u.first,u.last].filter(Boolean).join(" ")).join(", ")}}Uniques :
{{[...new Set($json.tags||[])].join(",")}}Somme sûre :
{{$json.items.reduce((s,x)=>s+(Number(x.price)||0),0)}}Comment gérer les dates dans les expressions n8n avec Luxon (guide avancé) ?
$now et $today (Luxon). Restez full-Luxon, fixez la zone tôt avec setZone() et formatez à la fin.ISO immédiat :
{{$now.toISO()}}Demain 18:00 Paris :
{{$today.setZone("Europe/Paris").plus({days:1}).set({hour:18}).toISO()}}Fin de mois :
{{$now.endOf("month").toISODate()}}Comment utiliser $jmespath() pour requêter un JSON dans les expressions n8n (comment) ?
$jmespath(obj, requête) applique une requête JMESPath : filtre, projection, aplanissement. Exemples :IDs payés :
{{$jmespath($json,"orders[?status=='paid'].id")}}Projection puis mise en forme :
{{$jmespath($json,"results[].{n:name,s:score}").map(x=>`${x.n}: ${x.s}`).join("\n")}}Tags uniques sur tous les items entrants :
{{[...new Set($jmespath($input.all(),"[].json.tags[]"))]}}Expressions n8n : quelles erreurs courantes éviter (aide) ?
[0] sans tester la longueur, la confusion || vs ??, et les expressions trop longues. Placez vos dérivés dans un nœud Set dédié et nommez clairement vos nœuds pour $("NomExact").Comment déboguer une expression n8n récalcitrante (support) ?
{{$json}} pour voir la réalité, puis ajoutez vos opérations étape par étape. Testez $jmespath() seul, vérifiez l’orthographe exacte des nœuds et les “linked items” dans l’éditeur de mapping.Comment construire une URL, des en-têtes et un payload dynamiques avec les expressions n8n (guide) ?
Endpoint :
{{ `${$("CONFIG").first().json.baseUrl}/users/${$json.id}?q=${encodeURIComponent($json.q||"")}` }}En-têtes filtrés :
{{ Object.fromEntries(Object.entries($("CONFIG").first().json.headers).filter(([k,v])=>v!=null)) }}Payload propre :
{{ JSON.stringify({ id:$json.id, when:$now.toISO(), tags:($json.tags||[]).filter(Boolean) }) }}Expressions n8n : quel est le bon usage de first(), last() et all() (tuto) ?
first() pour un résultat logique unique, last() pour récupérer la dernière exécution d’un nœud, all() pour agréger les items et les transformer avec map/flatMap. Renommez vos nœuds de façon stable pour garder des expressions lisibles.Puis-je tout faire en expressions n8n au lieu d’un Code node (guide) ?
Où apprendre à maîtriser les expressions n8n rapidement (aide, support) ?
$json, les expressions n8n lisibles et robustes, Luxon (zones, fenêtres temporelles, formats sûrs), et $jmespath() pour filtrer/projeter sans alourdir les workflows. Exercices guidés et snippets réutilisables inclus.⭐ Analytics engineer, Data Analyst et Automatisation IA indépendant ⭐
Ref clients : Logis Hôtel, Yelloh Village, BazarChic, Fédération Football Français, Texdecor…
Mon terrain de jeu :
Data Analyst & Analytics engineering : tracking avancé (GA4, Matomo, Piano, GTM server, Tealium, Commander Act, e-commerce, CAPI, RGPD), entrepôt de données (BigQuery, Snowflake, PostgreSQL, ClickHouse), modèles (Airflow, dbt, Dataform), dashboards décisionnels (Looker, Power BI, Metabase, SQL, Python).
Automatisation IA des taches Data, Marketing, RH, compta etc : conception de workflows intelligents robustes (n8n, App Script, scraping) connectés aux API de vos outils et LLM (OpenAI, Mistral, Claude…).
Engineering IA pour créer des applications et agent IA sur mesure : intégration de LLM (OpenAI, Mistral…), RAG, assistants métier, génération de documents complexes, APIs, backends Node.js/Python.





