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) :
🚀 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.
{ "email": "alice@example.com", "id": 42 }Expression dans un champ :
{{$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.






