Pour un premier thème classique livré à une association sportive locale, la question du logo m’a occupé plus longtemps que prévu. Le client changeait de logo tous les deux ou trois ans au gré des sponsors, et je ne voulais pas coder un chemin d’image en dur dans l’en-tête. La solution native de WordPress, add_theme_support('custom-logo'), répond exactement à ce besoin, mais sa mise en œuvre correcte demande de comprendre plusieurs pièces qui s’articulent ensemble.
Ce tutoriel reprend, dans l’ordre où je les ai résolues, les étapes pour afficher un logo entièrement gérable depuis le Customizer, sans dépendre d’un champ personnalisé ni d’un plugin. Il s’arrête au thème classique : l’équivalent pour un futur thème bloc, un concept encore émergent côté Gutenberg, passera par un mécanisme différent.
Étape 1 : déclarer le support dans functions.php
Tout commence par un appel à add_theme_support(), à placer dans une fonction accrochée au hook after_setup_theme. Sans cette déclaration, aucune option de logo n’apparaît dans Apparence > Personnaliser, même si le thème est par ailleurs fonctionnel.
function asc_setup_theme() {
add_theme_support( 'custom-logo', array(
'height' => 100,
'width' => 300,
'flex-height' => true,
'flex-width' => true,
) );
}
add_action( 'after_setup_theme', 'asc_setup_theme' );
Les paramètres height et width indiquent la taille recommandée affichée à l’utilisateur lors du choix de l’image dans la médiathèque. Les booléens flex-height et flex-width déterminent si une image de proportions différentes reste acceptée malgré tout : je les mets systématiquement à true, sauf sur les thèmes à en-tête très contraint où une déformation serait visible.
Étape 2 : afficher le logo avec get_custom_logo()
Une fois le support déclaré, la fonction get_custom_logo() retourne directement le balisage complet : une balise <a> vers l’accueil contenant une balise <img> avec les attributs srcset, alt et les classes attendues par la plupart des thèmes. Il suffit de l’appeler dans le template d’en-tête.
<div class="site-branding">
<?php
if ( function_exists( 'the_custom_logo' ) ) {
the_custom_logo();
}
?>
</div>
La fonction jumelle the_custom_logo() affiche directement le résultat de get_custom_logo() sans qu’il soit nécessaire d’appeler echo. Je préfère systématiquement cette forme dans les templates, réservant get_custom_logo() aux cas où le HTML doit être manipulé avant affichage.

Étape 3 : prévoir le cas où aucun logo n’est défini
Tant que l’utilisateur n’a pas encore choisi d’image dans le Customizer, has_custom_logo() renvoie faux et get_custom_logo() renvoie une chaîne vide. Un en-tête vide fait mauvaise impression sur un site tout juste installé ; j’ajoute donc systématiquement un repli vers le nom du site.
<div class="site-branding">
<?php if ( has_custom_logo() ) : ?>
<?php the_custom_logo(); ?>
<?php else : ?>
<p class="site-title">
<a href="<?php echo esc_url( home_url( '/' ) ); ?>">
<?php bloginfo( 'name' ); ?>
</a>
</p>
<?php endif; ?>
</div>
Étape 4 : gérer les tailles d’affichage réelles
Les paramètres height et width déclarés à l’étape 1 ne redimensionnent pas l’image affichée sur le site : ils servent uniquement d’indication dans l’écran d’administration. L’image réellement injectée dans le HTML dépend de la taille d’image WordPress la plus proche disponible dans la médiathèque, en général medium ou l’originale si aucune taille adaptée n’existe.
Pour un rendu net sur écrans à haute densité, j’invite le client à téléverser une image au moins deux fois plus large que la taille d’affichage prévue en CSS, et je contrains la hauteur réelle côté feuille de style plutôt que côté PHP, ce qui laisse WordPress générer le srcset correctement.
.site-branding img {
max-height: 60px;
width: auto;
}
Le filtre get_custom_logo pour aller plus loin
Sur un projet où le client voulait un logo différent en version mobile, j’ai utilisé le filtre get_custom_logo pour intercepter le HTML généré et y ajouter une classe conditionnelle, plutôt que de dupliquer la déclaration de support. Cette approche évite de réinventer un système déjà robuste pour un besoin qui relève surtout de CSS responsive.
Notre verdict
add_theme_support('custom-logo') reste la solution la plus fiable pour un logo administrable sans plugin sur un thème classique : elle s’appuie sur l’infrastructure native des tailles d’image et sur le Customizer, sans champ personnalisé à maintenir. Le seul travail restant à la charge du développeur est le repli textuel et l’ajustement CSS de la taille réelle affichée, deux détails vite oubliés mais qui font toute la différence pour un client qui changera son logo sans jamais rouvrir un fichier PHP.