vendredi 25 septembre 2026

À propos

Contact

Blocs Gutenberg

MediaUpload et MediaPlaceholder : créer un bloc image personnalisé

Sélection, remplacement, texte alternatif, rendu responsive dans save : le parcours complet pour un bloc image sur mesure, du placeholder vide à la publication.

Par Clément Hadrot • 6 août 2020 • 4 min de lecture • Aucun commentaire
MediaUpload et MediaPlaceholder : créer un bloc image personnalisé

Un bloc « portrait d’équipe » avec une seule image, un texte alternatif propre et un rendu qui respecte les dimensions réelles du fichier téléversé : voici étape par étape la construction complète, du placeholder vide jusqu’au rendu final côté front.

Étape 1 : déclarer les attributs

{
	"attributes": {
		"mediaId": { "type": "number" },
		"mediaUrl": { "type": "string", "default": "" },
		"mediaAlt": { "type": "string", "default": "" }
	}
}

Stocker l’identifiant (mediaId) en plus de l’URL n’est pas superflu : il permet de retrouver l’image dans la médiathèque, de la remplacer facilement, et surtout de régénérer les tailles d’image côté serveur si un thème change ses dimensions par défaut.

Étape 2 : l’état vide avec MediaPlaceholder

import { MediaPlaceholder } from '@wordpress/block-editor';

if ( ! attributes.mediaUrl ) {
	return (
		<MediaPlaceholder
			icon="format-image"
			labels={ { title: 'Portrait' } }
			onSelect={ ( media ) => {
				setAttributes( {
					mediaId: media.id,
					mediaUrl: media.url,
					mediaAlt: media.alt,
				} );
			} }
			accept="image/*"
			allowedTypes={ [ 'image' ] }
		/>
	);
}

MediaPlaceholder affiche par défaut un bouton d’import (glisser-déposer, sélection dans la médiathèque, ou saisie d’une URL externe selon la configuration). Il ne s’affiche que tant qu’aucune image n’est choisie, d’où la condition en tête de la fonction edit.

Étape 3 : remplacer l’image avec MediaUpload

L'essentiel à retenir : MediaPlaceholder gère l'état vide et l'import initial ; MediaUpload permet de remplacer une image déjà choisie ; Stocker id et url, jamais url seule, pour garder le lien vers la médiathèque

Une fois une image choisie, il faut permettre à l’auteur de la changer sans tout recommencer. MediaUpload encapsule ce comportement via une fonction de rendu (render props) :

import { MediaUpload } from '@wordpress/block-editor';
import { Button } from '@wordpress/components';

<MediaUpload
	onSelect={ ( media ) =>
		setAttributes( {
			mediaId: media.id,
			mediaUrl: media.url,
			mediaAlt: media.alt,
		} )
	}
	allowedTypes={ [ 'image' ] }
	value={ attributes.mediaId }
	render={ ( { open } ) => (
		<Button onClick={ open } variant="secondary">
			Changer l'image
		</Button>
	) }
/>

La prop value alimentée avec mediaId permet à la médiathèque de présélectionner l’image actuelle quand elle s’ouvre, un détail qui évite à l’utilisateur de devoir la rechercher à nouveau parmi des centaines de fichiers.

Étape 4 : le texte alternatif, souvent oublié

Le texte alternatif récupéré automatiquement (media.alt) correspond au champ renseigné dans la médiathèque, pas nécessairement adapté au contexte précis du bloc. Un champ TextControl dans l’inspecteur, relié à mediaAlt, permet de le personnaliser sans modifier la médiathèque globale :

<TextControl
	label="Texte alternatif"
	value={ attributes.mediaAlt }
	onChange={ ( mediaAlt ) => setAttributes( { mediaAlt } ) }
	help="Décrit l'image pour les lecteurs d'écran."
/>

Étape 5 : un rendu responsive dans save()

export default function save( { attributes } ) {
	const { mediaUrl, mediaAlt } = attributes;
	if ( ! mediaUrl ) return null;
	return (
		<figure>
			<img src={ mediaUrl } alt={ mediaAlt } loading="lazy" />
		</figure>
	);
}

L’attribut loading="lazy" sur l’élément img profite du chargement différé natif du navigateur sans script additionnel. Pour un rendu vraiment responsive avec plusieurs tailles (srcset), il est possible de basculer sur un bloc dynamique qui reconstruit la balise via wp_get_attachment_image côté PHP, au prix d’un aller-retour serveur supplémentaire.

  • Toujours prévoir un état où mediaUrl est vide, y compris dans save(), pour éviter un bloc cassé si l’attribut n’a jamais été rempli.
  • Ne jamais coder en dur un identifiant d’image issu d’un autre environnement : entre un serveur de développement et la production, les identifiants de la médiathèque ne coïncident pas forcément.

Un bloc image sans champ de texte alternatif accessible dans l’inspecteur reste, à nos yeux, un bloc incomplet, quelle que soit la qualité du reste de l’implémentation.

Notre verdict

MediaPlaceholder et MediaUpload couvrent, à eux deux, tout le cycle de vie d’une image dans un bloc personnalisé : sélection initiale, remplacement, et accès direct à la médiathèque native de WordPress sans réinventer un composant d’upload maison.

Partager :

À propos de l'auteur

Clément Hadrot

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi