Si vous avez déjà ajouté “juste une petite ligne” dans Divi et que tout votre header s’est mis à clignoter après une mise à jour, vous avez touché du doigt le vrai sujet : l’extension propre de Divi 5 passe par des hooks, pas par des modifications directes des templates.

Le problème / Le besoin

Divi 5 (April 2026) a beaucoup progressé côté performance et architecture, mais les besoins restent les mêmes sur les sites réels : ajouter une classe sur le body, injecter un attribut sur un bouton, modifier un module existant, charger un script uniquement sur certaines pages, ou encore tracer des infos en debug sans casser l’éditeur visuel.

Le souci, c’est que beaucoup de snippets “Divi hooks” qu’on trouve en ligne sont écrits pour d’anciennes générations (Divi 3/4), utilisent des hooks obsolètes, ou font du DOM hacking (jQuery qui cherche des sélecteurs instables). Ça marche… jusqu’au prochain update.

À la fin, vous saurez mettre en place une petite “couche d’extension” propre (mini-plugin) qui exploite les hooks WordPress (fiables) et, quand c’est pertinent, les points d’entrée Divi 5 (plus spécifiques), avec des exemples concrets et testables sur WordPress 6.9.4 et PHP 8.1+.

Résumé rapide

  • On évite les modifications de fichiers du thème Divi et les injections JS fragiles.
  • On crée un mini-plugin (ou un MU-plugin) pour centraliser vos hooks.
  • On utilise des hooks WordPress “socle” (ex : wp_enqueue_scripts, body_class, the_content, render_block, template_redirect).
  • On ajoute des adaptations Divi 5 quand nécessaire (détection du builder, chargement conditionnel, compatibilité front/éditeur).
  • On sécurise (capabilities, nonces, sanitization/escaping) et on garde un œil sur la performance.

Quand utiliser cette solution

  • Vous voulez personnaliser Divi 5 sans thème enfant (ou avec un thème enfant minimal) et sans perdre vos changements.
  • Vous devez ajouter des comportements (scripts, styles, attributs, classes, tracking) de façon conditionnelle (par page, par rôle, par type de contenu).
  • Vous maintenez plusieurs sites Divi et vous cherchez une approche reproductible (un plugin interne activable partout).
  • Vous avez des besoins compatibles avec l’éditeur (ne pas casser le Visual Builder / l’éditeur Divi).

Quand ne PAS utiliser cette solution

  • Votre besoin est purement “mise en page” (espacements, colonnes, styles). Dans ce cas, passez par les options Divi, le Theme Builder et le CSS natif, plutôt que du PHP.
  • Vous voulez “réécrire” un module Divi de fond en comble. Là, un module custom Divi 5 (ou un plugin dédié) est souvent plus propre qu’une collection de filtres.
  • Vous avez un site très complexe et vous devez versionner/tester sérieusement. Préférez une approche plugin + CI (tests, linters) plutôt que des snippets collés dans un plugin de type “Code Snippets”.

Prérequis / avant de commencer

  • WordPress 6.9.4 (ou plus récent) et PHP 8.1+. Si vous êtes en PHP 7.x, ne forcez pas : vous allez tomber sur des erreurs de syntaxe et des warnings.
  • Divi 5 à jour. Évitez de mélanger des tutos Divi 4 avec Divi 5 sans vérifier les équivalences.
  • Un environnement de test : staging, ou au minimum un backup complet (fichiers + base).
  • Accès aux logs (ou WP_DEBUG_LOG) pour voir les erreurs PHP.
  • Un plugin de cache peut masquer vos changements. Prévoyez de vider le cache (plugin + serveur + navigateur).

Sources utiles côté WordPress (officielles) :

L’approche naïve (et pourquoi l’éviter)

La version que je vois le plus souvent sur des sites Divi “qui ont grandi vite” : on ouvre header.php (ou un fichier du thème), on colle du PHP, on ajoute du JS dans “Code d’intégration” Divi, et on se dit que c’est réglé.

Exemple naïf typique

Injection de script partout, y compris dans l’éditeur, sans condition, sans versionning, sans dépendances :

<?php
// Anti-pattern : modification directe d'un fichier du thème + script inline non conditionnel
add_action('wp_footer', function () {
    echo '<script>console.log("tracking");</script>';
});
?>

Pourquoi ça casse (souvent)

  • Mises à jour : si vous modifiez le thème parent, vous perdez tout. Même avec un thème enfant, vous risquez des divergences.
  • Performance : chargement partout, pas de cache-busting, pas de dépendances, pas de condition (mobile/desktop/page).
  • Compatibilité builder : le Visual Builder charge des contextes spécifiques. Un script “global” peut casser l’édition (j’ai vu des boucles de re-render à cause d’un simple scroll listener).
  • Sécurité : sortie non échappée si vous affichez des données, absence de nonce si vous ajoutez des endpoints.

La bonne approche — tutoriel pas à pas

L’idée : créer un mini-plugin qui centralise vos hooks WordPress, et ajouter une petite couche “Divi-aware” (détection et conditions) pour éviter de charger des choses inutiles dans le builder.

Étape 1 — Créez un mini-plugin (recommandé)

Créez un dossier divi5-hooks-utiles dans wp-content/plugins/, puis un fichier divi5-hooks-utiles.php.

Pourquoi un plugin plutôt que functions.php : vous gardez vos personnalisations si vous changez de thème, et vous pouvez désactiver le tout en cas de problème (diagnostic).

Étape 2 — Ajoutez une “détection builder” pragmatique

Divi 5 évolue, et les fonctions internes peuvent changer. Je préfère une détection “dégradée” : on teste d’abord les constantes connues, puis des marqueurs de requête, et on reste permissif.

Objectif : ne pas charger certains scripts lourds quand on est dans le builder, et éviter de modifier le HTML de manière agressive pendant l’édition.

Étape 3 — Implémentez 6 hooks WordPress qui couvrent 80% des besoins

  • Action wp_enqueue_scripts : styles/scripts front, conditionnels.
  • Filtre body_class : classes contextuelles (page builder, template, etc.).
  • Filtre the_content : micro-ajustements (avec garde-fous).
  • Filtre nav_menu_link_attributes : attributs sur liens de menu (tracking, rel, aria).
  • Filtre script_loader_tag : defer/async proprement.
  • Action template_redirect : redirections propres, sans casser l’admin.

Étape 4 — Ajoutez un exemple “Divi concret” sans hook Divi fragile

Beaucoup de demandes “Divi” sont en réalité des demandes HTML : ajouter une classe sur certains boutons, ou injecter un attribut data-*. Le plus robuste reste souvent de cibler le rendu final via the_content avec une stratégie prudente (et testable), ou via CSS/JS conditionnels.

Je vous montre une approche raisonnable : on ne parse pas tout le DOM au hasard. On limite l’impact à des pages ciblées, et on évite le builder.

Code complet

Copiez-collez ce fichier tel quel dans wp-content/plugins/divi5-hooks-utiles/divi5-hooks-utiles.php, activez le plugin, puis testez sur une page Divi.

<?php
/**
 * Plugin Name: Divi 5 — Hooks utiles (actions & filtres)
 * Description: Une collection de hooks WordPress utiles, pensée pour des sites sous Divi 5 (WP 6.9.4+, PHP 8.1+).
 * Version:     1.0.0
 * Author:      Votre équipe
 * Requires at least: 6.9
 * Requires PHP: 8.1
 */

declare(strict_types=1);

if (!defined('ABSPATH')) {
	exit;
}

final class BPCAB_Divi5_Hooks_Utiles {

	private const VERSION = '1.0.0';
	private const HANDLE_FRONT = 'bpcab-divi5-front';

	public static function init(): void {
		// Front
		add_action('wp_enqueue_scripts', [__CLASS__, 'enqueue_front_assets'], 20);
		add_filter('script_loader_tag', [__CLASS__, 'filter_script_loader_tag'], 10, 3);

		// HTML / contenu
		add_filter('body_class', [__CLASS__, 'filter_body_class'], 20, 1);
		add_filter('nav_menu_link_attributes', [__CLASS__, 'filter_nav_menu_link_attributes'], 10, 4);
		add_filter('the_content', [__CLASS__, 'filter_the_content'], 12);

		// Routage
		add_action('template_redirect', [__CLASS__, 'maybe_redirect_legacy_urls'], 1);

		// Debug (désactivé par défaut, voir méthode)
		// add_action('wp_footer', [__CLASS__, 'debug_footer_comment'], 999);
	}

	/**
	 * Détection pragmatique du contexte "builder".
	 * - On évite de dépendre d'une API interne Divi trop spécifique.
	 * - On privilégie une détection "soft" via constantes et paramètres.
	 */
	private static function is_divi_builder_context(): bool {
		// Marqueurs historiques (peuvent varier selon versions/config)
		if (defined('ET_BUILDER_PLUGIN_ACTIVE') && ET_BUILDER_PLUGIN_ACTIVE) {
			return true;
		}

		// Paramètres fréquemment présents en mode builder/visual
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$et_fb = isset($_GET['et_fb']) ? sanitize_text_field(wp_unslash($_GET['et_fb'])) : '';
		if ($et_fb === '1') {
			return true;
		}

		// L'admin n'est pas le front
		if (is_admin()) {
			return false;
		}

		return false;
	}

	/**
	 * Charge des assets uniquement quand nécessaire.
	 * Exemple : un petit JS pour gérer des attributs data-*, ou un CSS correctif.
	 */
	public static function enqueue_front_assets(): void {
		if (is_admin()) {
			return;
		}

		// Exemple : ne pas charger dans le builder pour éviter les conflits d'édition.
		if (self::is_divi_builder_context()) {
			return;
		}

		// Exemple de condition : uniquement sur les pages (pas articles / archives).
		if (!is_page()) {
			return;
		}

		$src_js  = plugin_dir_url(__FILE__) . 'assets/front.js';
		$src_css = plugin_dir_url(__FILE__) . 'assets/front.css';

		wp_enqueue_style(
			self::HANDLE_FRONT,
			$src_css,
			[],
			self::VERSION
		);

		wp_enqueue_script(
			self::HANDLE_FRONT,
			$src_js,
			[],
			self::VERSION,
			['strategy' => 'defer'] // WP 6.3+ : support d'attributs via args
		);
	}

	/**
	 * Ajoute "defer" à un script ciblé (si votre WP ne prend pas en charge 'strategy' via args,
	 * ce filtre reste une solution fiable).
	 */
	public static function filter_script_loader_tag(string $tag, string $handle, string $src): string {
		if ($handle !== self::HANDLE_FRONT) {
			return $tag;
		}

		// Si le tag contient déjà defer/async, on évite le doublon.
		if (str_contains($tag, ' defer') || str_contains($tag, ' async')) {
			return $tag;
		}

		// Injection propre : on ajoute defer avant src.
		// Note : $tag est déjà un tag complet généré par WP.
		$tag = str_replace(' src=', ' defer src=', $tag);

		return $tag;
	}

	/**
	 * Ajoute des classes au body pour cibler CSS/JS proprement.
	 */
	public static function filter_body_class(array $classes): array {
		if (self::is_divi_builder_context()) {
			$classes[] = 'is-divi-builder';
		} else {
			$classes[] = 'is-divi-front';
		}

		if (is_page_template()) {
			$classes[] = 'has-page-template';
		}

		// Exemple : classe si l'utilisateur est connecté (utile pour masquer des CTA).
		if (is_user_logged_in()) {
			$classes[] = 'is-logged-in';
		}

		return array_values(array_unique($classes));
	}

	/**
	 * Ajoute des attributs aux liens de menu (tracking, sécurité, accessibilité).
	 */
	public static function filter_nav_menu_link_attributes(array $atts, $menu_item, $args, $depth): array {
		// Exemple : ajoute rel="nofollow" uniquement sur un menu spécifique via theme_location.
		if (isset($args->theme_location) && $args->theme_location === 'menu-principal') {
			// Ne pas écraser un rel existant, on concatène proprement.
			$existing_rel = isset($atts['rel']) ? (string) $atts['rel'] : '';
			$rels = array_filter(array_map('trim', explode(' ', $existing_rel)));

			if (!in_array('nofollow', $rels, true)) {
				$rels[] = 'nofollow';
			}
			$atts['rel'] = implode(' ', $rels);

			// Exemple : data attribute (pour analytics) — échappé au rendu par WP.
			$atts['data-menu'] = 'principal';
		}

		return $atts;
	}

	/**
	 * Micro-modification du contenu : ajoute un attribut data à certains boutons Divi.
	 * On reste prudent :
	 * - on cible uniquement les pages,
	 * - on évite le builder,
	 * - on n'applique pas sur les contenus trop volumineux (garde-fou).
	 */
	public static function filter_the_content(string $content): string {
		if (!is_singular() || !is_page()) {
			return $content;
		}

		if (self::is_divi_builder_context()) {
			return $content;
		}

		// Garde-fou perf : évite de traiter des contenus énormes (ex: page catalogue très longue).
		if (strlen($content) > 800000) { // ~800 KB
			return $content;
		}

		// Exemple concret : repérer les boutons Divi (classe fréquente "et_pb_button")
		// et ajouter data-cta="1" si absent.
		// Attention : on ne fait pas un parsing HTML complet ici (DOMDocument peut être lourd),
		// on applique une regex limitée sur un pattern précis.
		$pattern = '/<a([^>]*class="[^"]*et_pb_button[^"]*"[^>]*)>/i';

		$content = preg_replace_callback($pattern, static function (array $matches): string {
			$attrs = $matches[1];

			// Si data-cta existe déjà, on ne touche pas.
			if (stripos($attrs, 'data-cta=') !== false) {
				return '<a' . $attrs . '>';
			}

			// Injection : on ajoute un attribut data-cta.
			return '<a' . $attrs . ' data-cta="1">';
		}, $content);

		return is_string($content) ? $content : $content;
	}

	/**
	 * Exemple de redirection propre : anciennes URLs vers une nouvelle page.
	 * - Pas de redirection en admin
	 * - Pas de redirection pour les utilisateurs connectés (optionnel)
	 * - Utilise wp_safe_redirect
	 */
	public static function maybe_redirect_legacy_urls(): void {
		if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
			return;
		}

		// Optionnel : éviter de gêner les éditeurs connectés.
		if (is_user_logged_in() && current_user_can('edit_pages')) {
			return;
		}

		$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
		if ($request_uri === '') {
			return;
		}

		// Exemple : /promo-2024/ devient /offres/
		if (str_starts_with($request_uri, '/promo-2024')) {
			$target = home_url('/offres/');
			wp_safe_redirect($target, 301);
			exit;
		}
	}

	/**
	 * Debug non intrusif : ajoute un commentaire HTML en bas de page.
	 * Utile pour vérifier qu'un hook s'exécute sans polluer l'affichage.
	 */
	public static function debug_footer_comment(): void {
		if (!current_user_can('manage_options')) {
			return;
		}
		echo "n<!-- BPCAB Divi5 Hooks Utiles : actif | WP " . esc_html(get_bloginfo('version')) . " -->n";
	}
}

BPCAB_Divi5_Hooks_Utiles::init();

Ajoutez les fichiers assets (optionnels mais pratiques)

Créez wp-content/plugins/divi5-hooks-utiles/assets/front.js :

(function () {
  'use strict';

  // Exemple : tracer les clics sur les boutons marqués data-cta="1"
  document.addEventListener('click', function (e) {
    var el = e.target;
    if (!el) return;

    // Si on clique sur un span à l'intérieur du lien, on remonte.
    var link = el.closest ? el.closest('a[data-cta="1"]') : null;
    if (!link) return;

    // Ici vous brancherez votre outil analytics.
    // Gardez ça léger : pas de requête bloquante, pas d'erreur si analytics absent.
    if (window.console && console.debug) {
      console.debug('[CTA] click', link.href);
    }
  }, { passive: true });
})();

Créez wp-content/plugins/divi5-hooks-utiles/assets/front.css :

/* Exemple : style léger sur les CTA marqués */
a.et_pb_button[data-cta="1"] {
  outline-offset: 3px;
}

Explication du code

La logique (simple)

  • On charge un CSS/JS uniquement sur les pages, uniquement sur le front, et pas dans le builder.
  • On ajoute des classes au body pour cibler facilement vos règles CSS/JS.
  • On enrichit les liens de menu (ex : rel, data-*) sans toucher aux templates.
  • On modifie le contenu de façon prudente pour marquer certains boutons Divi avec data-cta.
  • On gère une redirection 301 propre (utile en refonte Divi).

Les hooks WordPress utilisés (précis)

  • wp_enqueue_scripts (action) : c’est le point d’entrée standard pour charger des assets front. Doc : wp_enqueue_scripts.
  • script_loader_tag (filtre) : permet d’altérer le tag <script> généré. Doc : script_loader_tag.
  • body_class (filtre) : ajoute des classes au <body> (super utile pour Divi). Doc : body_class.
  • nav_menu_link_attributes (filtre) : modifie les attributs des liens de menus. Doc : nav_menu_link_attributes.
  • the_content (filtre) : modifie le contenu rendu. Doc : the_content.
  • template_redirect (action) : point idéal pour rediriger avant le rendu du template. Doc : template_redirect.

Sécurité : ce qui est fait (et pourquoi)

  • Pas d’accès direct au fichier plugin (ABSPATH).
  • Sanitization des paramètres $_GET et $_SERVER via sanitize_text_field() + wp_unslash().
  • Redirection via wp_safe_redirect() (évite les open redirects). Doc : wp_safe_redirect().
  • Échappement</strong dans le debug via esc_html().

Performance : ce qui compte vraiment

  • Le hook the_content peut coûter cher si vous faites des regex lourdes sur des pages énormes. D’où le garde-fou de taille.
  • On évite de charger des assets dans le builder. C’est souvent là que les conflits arrivent (double frameworks, scripts qui interceptent des clics, etc.).
  • On versionne les assets avec une constante, pour un cache-busting simple.

Variantes et cas d’usage

Variante 1 — Ajouter une classe body par “template Divi Theme Builder”

Si vous avez des templates différents selon les pages, vous voulez parfois une classe unique par ID de page pour cibler un correctif CSS.

add_filter('body_class', function (array $classes): array {
	if (is_singular('page')) {
		$classes[] = 'page-id-' . get_queried_object_id();
	}
	return $classes;
}, 30);

Ce n’est pas spécifique à Divi, mais ça vous évite de multiplier les classes custom dans l’UI.

Variante 2 — Charger un script uniquement si la page contient un shortcode

J’ai souvent vu des sites Divi charger des scripts de slider partout, alors qu’une seule page en a besoin. Si votre contenu contient un shortcode (ou un bloc), conditionnez l’enqueue.

add_action('wp_enqueue_scripts', function (): void {
	if (!is_singular()) {
		return;
	}

	$post = get_post();
	if (!$post instanceof WP_Post) {
		return;
	}

	if (!has_shortcode($post->post_content, 'mon_shortcode')) {
		return;
	}

	wp_enqueue_script(
		'mon-shortcode-js',
		plugin_dir_url(__FILE__) . 'assets/shortcode.js',
		[],
		'1.0.0',
		['strategy' => 'defer']
	);
}, 20);

Doc : has_shortcode().

Variante 3 — Modifier le rendu d’un bloc Gutenberg inséré dans une page Divi

Divi et Gutenberg cohabitent souvent (FAQ en blocs, patterns, etc.). Le filtre render_block vous permet de cibler un bloc précis sans toucher au contenu brut.

add_filter('render_block', function (string $block_content, array $block): string {
	if (($block['blockName'] ?? '') !== 'core/button') {
		return $block_content;
	}

	// Ajoute un attribut data sur le HTML rendu si absent.
	if (str_contains($block_content, 'data-cta=')) {
		return $block_content;
	}

	return str_replace('<a ', '<a data-cta="1" ', $block_content);
}, 10, 2);

Doc : render_block.

Compatibilité Divi 5 / Elementor / Avada

Divi 5

  • Les hooks WordPress utilisés ici restent stables, même si Divi change son rendu interne.
  • Le point sensible est la détection du builder. Le snippet proposé est volontairement “soft”. Si votre site a un workflow précis, adaptez is_divi_builder_context() (par exemple en ajoutant un header, un cookie interne, etc.).
  • Évitez d’injecter des scripts globaux qui interceptent les clics/drag & drop : c’est le scénario classique de “le Visual Builder ne répond plus”.

Elementor

Sur Elementor, la logique est la même : vous conditionnez l’enqueue et vous évitez d’agir dans le contexte éditeur. Elementor expose des marqueurs différents (paramètres, actions PHP). Si vous devez supporter les deux, centralisez une fonction “is_builder_context()” et ajoutez un test Elementor en plus.

Référence (code & hooks Elementor) : Elementor sur GitHub (utile pour vérifier les points d’entrée et éviter les snippets inventés).

Avada (Fusion Builder)

Avada charge aussi des assets spécifiques en mode builder. Même conseil : pas de DOM hacking global, chargez vos scripts uniquement sur les pages qui en ont besoin, et mettez des garde-fous.

Si vous utilisez des éléments Avada/shortcodes, la variante “has_shortcode” devient particulièrement rentable.

Vérifications après mise en place

  • Activez le plugin, rechargez une page (front) et vérifiez que assets/front.js et assets/front.css sont bien chargés (DevTools > Network).
  • Inspectez le <body> : vous devez voir is-divi-front ou is-divi-builder.
  • Sur une page avec un bouton Divi, inspectez le HTML : le lien doit avoir data-cta="1" si la classe et_pb_button est présente.
  • Testez la redirection (ex : /promo-2024/) en navigation privée.
  • Videz le cache (plugin + serveur/CDN) si vous ne voyez rien changer.

Tableau de diagnostic rapide

Symptôme Cause probable Vérification Solution
Les assets ne se chargent pas Vous n’êtes pas sur une page, ou vous êtes en contexte builder DevTools Network + vérifiez is_page() et et_fb=1 Ajustez les conditions dans enqueue_front_assets()
Rien ne change malgré le plugin actif Cache (plugin/CDN/navigateur) Désactivez temporairement le cache ou force refresh Videz tous les caches, incrémentez VERSION
Erreur 500 après activation Syntaxe PHP (point-virgule manquant) ou PHP trop ancien Consultez wp-content/debug.log / logs serveur Corrigez la syntaxe, passez en PHP 8.1+
Le Visual Builder se comporte mal Script chargé dans le builder, conflit JS Ouvrez builder, regardez la console Renforcez is_divi_builder_context(), ne chargez pas le JS
Les boutons n’ont pas data-cta Classe différente, ou contenu non filtré (module spécial) Inspectez le HTML exact du bouton Adaptez la regex (ou passez par CSS/JS ciblé)

Si ça ne marche pas

  1. Confirmez l’emplacement : le fichier doit être dans wp-content/plugins/divi5-hooks-utiles/divi5-hooks-utiles.php. J’ai vu des gens le coller dans wp-content/plugins/divi5-hooks-utiles.php (mauvais niveau), WordPress ne le détecte pas.
  2. Désactivez temporairement tous les plugins de snippets et minification (autoptimize, perf plugins). Les concaténations peuvent casser l’ordre des scripts.
  3. Activez le debug sur staging :
    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
    define('WP_DEBUG_DISPLAY', false);
  4. Regardez les logs : une erreur “Call to undefined function” arrive souvent quand on copie un code d’un ancien tuto (ou quand on a un fichier chargé trop tôt).
  5. Testez sans Divi Builder (front simple). Si ça marche hors builder mais pas dedans, le problème est presque toujours un script ou une condition trop large.
  6. Vérifiez les priorités : si un autre plugin filtre the_content après vous et “réécrit” le HTML, votre injection peut disparaître. Montez/descendez la priorité (12, 20, etc.).

Pièges et erreurs courantes

Erreur Cause Solution
Code collé dans le mauvais fichier Ajout dans un module Divi “Code”, ou dans le thème parent Utilisez un mini-plugin (ou MU-plugin) et versionnez
Parse error: syntax error Parenthèse/point-virgule manquant, ou copier-coller tronqué Re-copiez le fichier complet, vérifiez les accolades
Fatal error après update Snippet d’un ancien tutoriel incompatible PHP 8.1+ Supprimez le snippet, remplacez par une version typée et testée
Confusion action/filtre Utiliser add_action sur un filtre (ou inversement) Rappelez-vous : filtre retourne une valeur, action non
Le script ne se charge pas Mauvais hook (ex : init) ou mauvais handle Chargez sur wp_enqueue_scripts, vérifiez le handle dans la page
Le CSS/JS change mais “revient en arrière” Cache + minification + CDN Incrémentez la version d’asset, purge CDN, purge plugin
Redirection en boucle Condition trop large dans template_redirect Testez précisément REQUEST_URI, évitez les starts-with trop vagues
Le builder plante JS global qui intercepte des événements (click/drag/scroll) Ne chargez pas dans le builder, ou isolez le code avec conditions strictes

Conseils sécurité, performance et maintenance

  • Préférez un plugin à des snippets dispersés. Quand un site Divi a 12 endroits où du code est injecté, le dépannage devient une loterie.
  • Évitez les regex “générales” sur the_content. Si vous devez faire du HTML sérieux, envisagez DOMDocument (mais testez la perf), ou ciblez plutôt des blocs via render_block.
  • Ne chargez pas jQuery “par habitude”. Divi peut déjà embarquer beaucoup de JS. Ajoutez le minimum viable.
  • Redirections : utilisez wp_safe_redirect et sortez avec exit. Ne redirigez jamais en vous basant sur une URL fournie par l’utilisateur sans validation stricte (risque d’open redirect).
  • Maintenance : gardez un changelog interne. Quand Divi ou WP changent, vous saurez quel hook désactiver en premier.

Pour suivre les changements côté WordPress (pratique quand un hook change de comportement) :

Ressources

FAQ

Quels sont les “hooks Divi 5” les plus fiables en 2026 ?

Pour du code durable, misez d’abord sur les hooks WordPress (ceux utilisés ici). Les hooks internes Divi existent, mais ils évoluent plus vite et sont moins documentés publiquement. Dans la pratique, 80% des personnalisations “Divi” passent très bien par wp_enqueue_scripts, body_class, the_content et des filtres d’attributs.

Pourquoi éviter de modifier les fichiers du thème Divi ?

Parce que vous perdez vos changements à la mise à jour (thème parent) ou vous créez une dette de maintenance (thème enfant avec overrides massifs). Un plugin garde vos modifications isolées et désactivables.

Est-ce que the_content est “sale” ?

Pas forcément. C’est un hook puissant, mais facile à abuser. Si vous l’utilisez, mettez des conditions strictes, un garde-fou sur la taille, et évitez les regex trop générales.

Pourquoi mon script ne se charge pas alors que le plugin est actif ?

Le cas le plus fréquent : vous testez dans le builder (et le code a volontairement un return), ou vous êtes sur un type de page exclu par is_page(). Deuxième cause : cache/minification.

Comment ajouter defer proprement sur WordPress 6.9.4 ?

Deux options : passer l’argument ['strategy' => 'defer'] à wp_enqueue_script(), et/ou utiliser script_loader_tag pour cibler un handle précis. Le filtre reste utile si un autre outil “réécrit” vos tags.

Est-ce compatible avec un site multilingue (Polylang/WPML) ?

Oui, mais attention aux redirections : adaptez les URLs cibles avec la logique du plugin multilingue (souvent via des fonctions dédiées) pour éviter de rediriger vers la mauvaise langue.

Où placer ce code si je n’ai pas accès à FTP ?

Techniquement, vous pouvez le coller dans un plugin de snippets, mais c’est moins fiable (export, ordre de chargement, rollback). Si vous n’avez pas FTP, essayez au minimum un plugin qui supporte la désactivation automatique en cas d’erreur fatale, et testez sur staging.

Comment savoir si je suis “dans le builder” Divi ?

Il n’y a pas une vérité unique. Le snippet teste des marqueurs courants (constante et paramètre et_fb=1). Sur certains setups, vous devrez ajouter vos propres signaux (ex : vérifier une route spécifique, ou un cookie). Testez en ouvrant le Visual Builder et en observant l’URL.

Puis-je transformer ça en MU-plugin ?

Oui. Placez le fichier dans wp-content/mu-plugins/. Avantage : toujours actif. Inconvénient : moins simple à désactiver pour dépanner. Sur des sites clients, je préfère un plugin standard + un process de déploiement.

Quelle est la meilleure méthode pour ajouter un attribut sur un bouton Divi ?

Si vous contrôlez le bouton (module), la meilleure méthode est souvent d’ajouter une classe/attribut via l’UI Divi. Si vous devez le faire globalement, utilisez une approche ciblée (regex limitée, ou JS conditionnel), et évitez de casser l’éditeur.