
Dans WooCommerce, la page de connexion existe déjà : c’est la page Mon compte. Tant que le client n’est pas connecté, elle affiche le formulaire de connexion (et celui d’inscription si vous l’activez), tiré du template myaccount/form-login.php ; une fois connecté, il y retrouve ses commandes et ses adresses. Pour personnaliser la page de connexion WooCommerce, il est donc rarement utile d’en créer une autre : on règle la page Mon compte, on ajoute du contenu avec les hooks, on surcharge le template dans un thème enfant si la structure doit changer, et on choisit la destination après connexion avec le filtre woocommerce_login_redirect.
Je développe sur WordPress depuis 14 ans, notamment des boutiques WooCommerce et des sites Avada. Ce guide suit l’ordre dans lequel je traite ce type de demande : le fonctionnement, le choix de la méthode, puis le code, vérifié dans les sources de WooCommerce. La page de connexion séparée n’arrive qu’après les méthodes natives : elle est rarement utile et cache deux pièges, le cache et les redirections.
Comment fonctionne la page de connexion de WooCommerce
La page Mon compte sert de page de connexion
À l’installation, WooCommerce crée une page « Mon compte » (/mon-compte/ sur un site en français) qui contient le shortcode [woocommerce_my_account]. Elle est désignée dans WooCommerce > Réglages > Avancé > Installation des pages > Page Mon compte. Ce shortcode affiche l’espace client à un visiteur connecté, le formulaire de connexion aux autres.
Les sous-pages (commandes, adresses, mot de passe perdu…) sont des « terminaisons » ajoutées à cette adresse, comme /mon-compte/orders/, réglables dans la rubrique Terminaisons du compte.
Les réglages qui modifient le formulaire
Avant d’écrire du code, ouvrez WooCommerce > Réglages > Comptes et confidentialité (documentation de ces réglages, en anglais) :
- Options de création de compte : l’option Sur la page « Mon compte » ajoute le formulaire d’inscription en deuxième colonne ;
- « Envoyer un lien de configuration du mot de passe (recommandé) » : l’inscription ne demande plus de mot de passe, le client le choisit depuis l’e-mail reçu ;
- « Autoriser la connexion lors de la validation de la commande » : un formulaire de connexion repliable apparaît sur la page de commande ;
- Politique de confidentialité de l’inscription : le texte affiché sous le formulaire d’inscription.
Formulaire WooCommerce ou wp-login.php : deux circuits différents
La page wp-login.php de WordPress reste la porte d’entrée de l’administration. Le formulaire de Mon compte n’en dépend pas : WooCommerce le traite lui-même, avec son propre jeton de sécurité (le nonce woocommerce-login), puis connecte le client avec wp_signon(). Conséquences :
- les filtres
woocommerce_login_redirectetwoocommerce_registration_redirectne concernent que les formulaires WooCommerce ; sur wp-login.php, c’est le filtre login_redirect de WordPress qui décide ; - le lien « Mot de passe perdu ? » mène déjà vers Mon compte, pas vers wp-login.php ;
- un client qui ouvre
wp-adminest renvoyé vers Mon compte, et la barre d’administration lui est masquée : rien à coder.
Bloquer wp-login.php pour tout le monde est donc inutile, et risqué pour l’accès de l’équipe à l’administration.
Quelle méthode choisir selon votre besoin
La plupart des demandes se règlent sans toucher au template :
| Besoin | Méthode | Compétences | Point de vigilance |
|---|---|---|---|
| Ajouter un texte, un lien ou une mention | Hooks du formulaire | Quelques lignes de PHP | Certains hooks servent aussi au formulaire de la page de commande |
| Changer les couleurs, les espacements, le bouton | CSS | CSS | Garder les libellés visibles et le focus clavier |
| Réorganiser le formulaire | Surcharge du template form-login.php | PHP et HTML | À revérifier après chaque mise à jour de WooCommerce |
| Choisir la page affichée après connexion ou inscription | Filtres de redirection | Quelques lignes de PHP | Ne pas sortir le client du tunnel de commande |
| Afficher le formulaire sur une autre page | Shortcode maison avec woocommerce_login_form() | PHP | Page à exclure du cache |
| Mettre en page sans code | Constructeur de pages ou extension dédiée | Aucun code | Vérifier quel formulaire est réellement utilisé |
Le code de cet article se place dans le functions.php d’un thème enfant ou, mieux, dans une petite extension propre au site, qui survit à un changement de thème. Un dossier wp-content/plugins/ma-boutique-connexion/ contenant ce fichier (par exemple ma-boutique-connexion.php) suffit ; l’en-tête Requires Plugins (WordPress 6.5 et plus) empêche de l’activer sans WooCommerce.
<?php
/**
* Plugin Name: Ma boutique : connexion client
* Description: Personnalisation de la page de connexion et de Mon compte WooCommerce.
* Version: 1.0.0
* Requires PHP: 7.4
* Requires Plugins: woocommerce
* Text Domain: ma-boutique-connexion
*/
defined( 'ABSPATH' ) || exit;
// Collez les extraits de cet article à la suite.
Quand les personnalisations s’accumulent (champs, onglets, règles propres à la boutique), mieux vaut les regrouper dans une extension sur mesure documentée que les éparpiller dans functions.php.
Ajouter du contenu au formulaire avec les hooks
Les hooks du template myaccount/form-login.php
Le template de Mon compte prévoit des points d’accroche à chaque endroit utile, ce qui évite la plupart des surcharges :
woocommerce_before_customer_login_formetwoocommerce_after_customer_login_form: avant et après le bloc complet (connexion et inscription) ;woocommerce_login_form_start,woocommerce_login_formetwoocommerce_login_form_end: au début du formulaire de connexion, après le mot de passe, et juste avant la fermeture du formulaire ;woocommerce_register_form_start,woocommerce_register_formetwoocommerce_register_form_end: les mêmes emplacements dans le formulaire d’inscription.
Exemple : un message au-dessus du formulaire
Le texte passe par esc_html__() : il est échappé et reste traduisible.
/**
* Message au-dessus des champs de connexion, sur la page Mon compte uniquement.
* Le hook woocommerce_login_form_start sert aussi au formulaire de la page de commande :
* is_account_page() évite d'y afficher ce texte.
*/
function ma_boutique_login_intro() {
if ( ! is_account_page() ) {
return;
}
echo '<p class="ma-boutique-login-intro">' . esc_html__( 'Connectez-vous pour suivre vos commandes et retrouver vos adresses.', 'ma-boutique-connexion' ) . '</p>';
}
add_action( 'woocommerce_login_form_start', 'ma_boutique_login_intro' );
La condition is_account_page() n’est pas décorative : les trois hooks woocommerce_login_form* existent aussi dans le formulaire de connexion de la page de commande. Sans elle, le message apparaîtrait dans le tunnel d’achat.
Modifier la structure avec le template form-login.php
Copier le template dans le thème enfant
Pour déplacer des champs ou changer le balisage, on surcharge le template : WooCommerce cherche d’abord le fichier dans le dossier woocommerce/ du thème actif (documentation de la structure des templates). L’original, lui, est remplacé à chaque mise à jour. Au besoin, commencez par créer un thème enfant.
Original (ne pas modifier, écrasé à chaque mise à jour) :
wp-content/plugins/woocommerce/templates/myaccount/form-login.php
Copie à modifier :
wp-content/themes/votre-theme-enfant/woocommerce/myaccount/form-login.php
Vérifiez d’abord que le thème parent ne surcharge pas déjà ce fichier ; si oui, partez de sa version. Avada ne surcharge pas myaccount/form-login.php : il passe par des hooks.
Ce qu’il ne faut pas retirer du template
Une surcharge peut casser la connexion sans aucun message d’erreur. Conservez :
- la ligne
wp_nonce_field( 'woocommerce-login', 'woocommerce-login-nonce' ): sans ce jeton, WooCommerce ignore l’envoi du formulaire, qui se recharge simplement ; - les attributs
namedes champs (username,password,rememberme) et du bouton (login) ; - les appels
do_action(): des extensions (sécurité, captcha, connexion sociale) s’y accrochent ; - les attributs
autocomplete, qui permettent aux gestionnaires de mots de passe de remplir le formulaire ; - les libellés
<label>associés aux champs, indispensables aux lecteurs d’écran, et le lien « Mot de passe perdu ? ».
Suivre les mises à jour du template
Chaque template porte un numéro @version : à la date de cet article, myaccount/form-login.php est en version 9.9.0. Quand WooCommerce le fait évoluer, votre copie ne suit pas. WooCommerce > État > État du système liste vos surcharges dans la section Modèles et signale les obsolètes (procédure de mise à jour). Ces templates bougent : form-order-withdrawal.php est apparu dans Mon compte avec la version 11.1. C’est pourquoi je préfère les hooks quand ils suffisent, comme pour toute extension : voir comment modifier une extension sans perdre ses modifications.
Rediriger après la connexion et l’inscription
Ce que fait vraiment woocommerce_login_redirect
C’est une demande courante, et le code qui circule est souvent faux. Le filtre woocommerce_login_redirect ne redirige pas la page de connexion : il s’exécute après une connexion réussie et reçoit la destination prévue, choisie dans cet ordre : le champ caché redirect du formulaire, sinon le référent, c’est-à-dire la page qui affichait le formulaire (souvent un simple chemin relatif comme /mon-compte/), sinon Mon compte. Le résultat passe ensuite par wp_validate_redirect(), qui écarte les domaines extérieurs.
Le piège : un filtre qui renvoie toujours la même page fait sortir du tunnel de commande le client qui se connecte depuis la page de paiement. Ne remplacez que la destination par défaut, en comparant les chemins plutôt que les URL complètes :
/**
* Après connexion depuis Mon compte : ouvrir directement la liste des commandes.
* $redirect vaut, dans l'ordre : le champ caché « redirect », le référent, puis Mon compte.
* On ne remplace que cette destination par défaut : un client qui se connecte depuis
* la page de commande y revient, et l'équipe du site garde le comportement normal.
*/
function ma_boutique_login_redirect( $redirect, $user ) {
if ( ! $user instanceof WP_User || user_can( $user, 'edit_posts' ) ) {
return $redirect;
}
// Le référent est souvent un chemin relatif (/mon-compte/) : on compare chemin et paramètres.
$target = wp_parse_url( (string) $redirect );
$account = wp_parse_url( wc_get_page_permalink( 'myaccount' ) );
if (
is_array( $target ) && is_array( $account )
&& untrailingslashit( $target['path'] ?? '' ) === untrailingslashit( $account['path'] ?? '' )
&& ( $target['query'] ?? '' ) === ( $account['query'] ?? '' )
) {
return wc_get_account_endpoint_url( 'orders' );
}
return $redirect;
}
add_filter( 'woocommerce_login_redirect', 'ma_boutique_login_redirect', 10, 2 );
Après l’inscription : woocommerce_registration_redirect
Après une inscription, WooCommerce applique un autre filtre, à un seul argument. Ici, le nouveau client arrive sur ses adresses :
/**
* Après inscription : inviter le nouveau client à compléter ses adresses.
* Ce filtre ne reçoit qu'un argument.
*/
function ma_boutique_registration_redirect( $redirect ) {
return wc_get_account_endpoint_url( 'edit-address' );
}
add_filter( 'woocommerce_registration_redirect', 'ma_boutique_registration_redirect' );
Ramener le client sur la page d’où il vient
Pour qu’un lien « Se connecter » placé sur une fiche produit y ramène le client, ajoutez l’adresse de retour au lien (/mon-compte/?redirect_to=…) et transmettez-la au formulaire :
/**
* Lien « Se connecter » de la forme /mon-compte/?redirect_to=URL :
* transmet l'URL de retour au formulaire de Mon compte.
* WooCommerce revalide ensuite cette adresse avec wp_validate_redirect().
*/
function ma_boutique_login_redirect_field() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- simple URL de retour, revalidée.
if ( ! is_account_page() || empty( $_GET['redirect_to'] ) ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$redirect = wp_validate_redirect( esc_url_raw( wp_unslash( $_GET['redirect_to'] ) ), '' );
if ( $redirect ) {
printf( '<input type="hidden" name="redirect" value="%s" />', esc_url( $redirect ) );
}
}
add_action( 'woocommerce_login_form_end', 'ma_boutique_login_redirect_field' );
Dans les menus, faites simplement pointer « Se connecter » vers Mon compte. Je déconseille de détourner globalement l’adresse de connexion avec le filtre login_url : WordPress s’en sert pour reconnaître wp-login.php (is_login()) et pour construire les liens du mode de récupération envoyés après une erreur fatale.
Les formulaires de connexion des constructeurs de pages
Sur un site Avada, l’élément « Connexion utilisateur » d’Avada Builder envoie ses données à wp-login.php, pas au circuit de WooCommerce : les filtres woocommerce_* ne s’y appliquent pas. On règle alors la destination dans l’option de redirection de l’élément ou avec le filtre login_redirect. Pour les widgets de connexion d’Elementor Pro ou d’un autre constructeur, vérifiez de même quel circuit ils utilisent en testant une connexion. Pour le reste de la boutique, les constructeurs restent pratiques, par exemple pour personnaliser la fiche produit WooCommerce avec Elementor.
Créer une page de connexion séparée, seulement si c’est utile
Une page dédiée se justifie pour une page d’atterrissage, un accès réservé aux revendeurs ou une mise en page très différente de l’espace client. La version précédente de cet article proposait trois choses qui ne fonctionnaient pas : un filtre de redirection mal compris, un modèle de page qui appelait wp_redirect() après l’affichage du HTML (trop tard : selon la configuration du serveur, la redirection échoue avec l’avertissement « headers already sent ») et un shortcode qui affichait tout l’espace client. Voici la méthode qui fonctionne.
Afficher le formulaire avec un shortcode
Créez une page « Connexion » (slug connexion), placez-y le shortcode [ma_boutique_connexion] et ajoutez ce code :
/**
* Shortcode [ma_boutique_connexion] : formulaire de connexion seul, pour une page séparée.
* woocommerce_login_form() charge global/form-login.php (le formulaire de la page de commande),
* pas myaccount/form-login.php : les messages d'erreur sont à afficher soi-même.
*/
function ma_boutique_login_form_shortcode() {
if ( ! function_exists( 'woocommerce_login_form' ) || is_user_logged_in() ) {
return '';
}
ob_start();
wc_print_notices();
woocommerce_login_form(
array(
'message' => esc_html__( 'Connectez-vous pour suivre vos commandes.', 'ma-boutique-connexion' ),
'redirect' => wc_get_page_permalink( 'myaccount' ),
)
);
return ob_get_clean();
}
add_shortcode( 'ma_boutique_connexion', 'ma_boutique_login_form_shortcode' );
Deux détails comptent. woocommerce_login_form() affiche le template global/form-login.php, celui de la page de commande : c’est lui qu’il faudrait surcharger, pas celui de Mon compte. Et sur une page ordinaire, rien n’affiche en général les messages de WooCommerce : sans wc_print_notices(), un mot de passe erroné ne produit aucun message.
Rediriger un client déjà connecté
Une redirection doit partir avant tout envoi de HTML, donc depuis le hook template_redirect, avec wp_safe_redirect() suivi de exit :
/**
* Client déjà connecté qui ouvre la page /connexion/ : direction Mon compte.
* template_redirect s'exécute avant l'envoi du moindre HTML.
*/
function ma_boutique_redirect_logged_in_customer() {
if ( is_user_logged_in() && is_page( 'connexion' ) ) {
wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) );
exit;
}
}
add_action( 'template_redirect', 'ma_boutique_redirect_logged_in_customer' );
Exclure la page du cache
C’est le piège le moins visible. WooCommerce interdit la mise en cache du panier, de la commande et de Mon compte, et WP Rocket exclut automatiquement ces trois pages. Votre page « Connexion », elle, est mise en cache comme une page ordinaire, avec le jeton de sécurité du formulaire figé dans le HTML. Deux problèmes en découlent. D’abord, pour un visiteur non connecté qui a déjà une session WooCommerce (après un ajout au panier, par exemple), WooCommerce rattache ce jeton à la session : le jeton figé, créé pour un autre visiteur, ne correspond pas. Ensuite, un jeton n’est valable que 12 à 24 heures : si la copie en cache vit plus longtemps (WP Rocket conseille une durée de vie du cache inférieure à 12 heures pour cette raison), il expire pour tout le monde. Dans les deux cas, le formulaire se recharge sans message et le client reste déconnecté. La solution est d’ajouter la page aux URL à ne jamais mettre en cache (recommandations de WooCommerce) ; voir aussi les pages à exclure du cache sur une boutique WooCommerce.
Personnaliser l’apparence du formulaire en CSS
Pour les couleurs, les espacements et le bouton, le style.css du thème enfant ou le champ de CSS personnalisé du thème suffit. Les classes utiles : .woocommerce-form-login pour le formulaire, .woocommerce-form-login__submit pour le bouton, .woocommerce-form-register pour l’inscription, et #customer_login .u-column1 / .u-column2 pour les deux colonnes.
/* Carte autour du formulaire de connexion (page Mon compte) */
.woocommerce-account .woocommerce .woocommerce-form-login {
max-width: 480px;
padding: 32px;
background: #ffffff;
border: 1px solid #c9ced6;
border-radius: 8px;
}
/* Bouton « Se connecter » : contraste élevé, zone cliquable confortable */
.woocommerce-account .woocommerce .woocommerce-form-login__submit {
width: 100%;
min-height: 48px;
background: #05233e;
color: #ffffff;
}
.woocommerce-account .woocommerce .woocommerce-form-login__submit:hover {
background: #04182b;
color: #ffffff;
}
/* Focus clavier toujours visible */
.woocommerce-account .woocommerce-form-login input:focus-visible,
.woocommerce-account .woocommerce-form-login__submit:focus-visible {
outline: 3px solid #05233e;
outline-offset: 2px;
}
Le préfixe .woocommerce-account .woocommerce l’emporte sur les styles de WooCommerce sans !important ; votre thème peut ajouter les siens, vérifiez avec l’inspecteur du navigateur. Côté accessibilité : ne remplacez pas les libellés par de simples textes indicatifs, gardez un focus visible, un contraste suffisant et des zones cliquables d’au moins 44 pixels de haut sur mobile.
Personnaliser le reste de la page Mon compte
Retirer ou renommer un onglet
Le menu de Mon compte passe par le filtre woocommerce_account_menu_items. Sans produits téléchargeables, l’onglet « Téléchargements » est inutile :
/**
* Menu de Mon compte : retirer « Téléchargements » et renommer « Détails du compte ».
*/
function ma_boutique_account_menu_items( $items ) {
unset( $items['downloads'] );
if ( isset( $items['edit-account'] ) ) {
$items['edit-account'] = __( 'Mes informations', 'ma-boutique-connexion' );
}
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'ma_boutique_account_menu_items' );
Sans code, vider le slug d’une terminaison dans Terminaisons du compte retire aussi l’onglet du menu.
Ajouter un onglet
Il faut déclarer une terminaison, l’ajouter au menu et afficher son contenu avec le hook woocommerce_account_{terminaison}_endpoint (voir la documentation des endpoints WooCommerce).
/**
* Nouvel onglet « Assistance » dans Mon compte (/mon-compte/assistance/).
* Après l'ajout du code : Réglages > Permaliens > Enregistrer les modifications.
*/
function ma_boutique_query_vars( $vars ) {
$vars['assistance'] = 'assistance';
return $vars;
}
add_filter( 'woocommerce_get_query_vars', 'ma_boutique_query_vars' );
function ma_boutique_menu_assistance( $items ) {
$logout = array();
if ( isset( $items['customer-logout'] ) ) {
$logout = array( 'customer-logout' => $items['customer-logout'] );
unset( $items['customer-logout'] );
}
$items['assistance'] = __( 'Assistance', 'ma-boutique-connexion' );
return $items + $logout; // « Se déconnecter » reste en dernier.
}
add_filter( 'woocommerce_account_menu_items', 'ma_boutique_menu_assistance', 20 );
function ma_boutique_assistance_content() {
echo '<p>' . esc_html__( 'Une question sur une commande ? Indiquez son numéro dans le formulaire de contact.', 'ma-boutique-connexion' ) . '</p>';
}
add_action( 'woocommerce_account_assistance_endpoint', 'ma_boutique_assistance_content' );
Un onglet en erreur 404 signifie presque toujours que les permaliens n’ont pas été réenregistrés.
Les extensions de personnalisation de Mon compte
Pour réorganiser l’espace client sans code, des extensions existent, comme « Customize My Account for WooCommerce » ou « My Account Page Editor » sur la place de marché de WooCommerce. Vérifiez leur date de mise à jour et leur compatibilité, et testez-les en préproduction : chacune s’ajoute à la liste des extensions à maintenir.
Sécurité et fiabilité de la connexion
Règle principale : ne réécrivez pas l’authentification et ne créez pas les cookies de session vous-même. Le formulaire de WooCommerce passe par wp_signon(), la fonction standard de WordPress, sur laquelle s’appuient les protections habituelles. Sur une boutique en production, je vérifie :
- la limitation des tentatives de connexion : sur les sites que je maintiens, Wordfence sert de pare-feu. Quelle que soit l’extension de sécurité, vérifiez qu’elle protège aussi le formulaire de Mon compte en faisant quelques essais avec un mauvais mot de passe, pas seulement sur wp-login.php ;
- HTTPS sur tout le site, pour que les identifiants ne circulent jamais en clair ;
- la double authentification pour les comptes de l’équipe, les plus exposés ;
- des tests après chaque mise à jour de WooCommerce, du thème ou d’une extension de sécurité : connexion, inscription, mot de passe perdu et connexion depuis la page de commande, d’abord en préproduction. C’est l’un des contrôles que je fais sur l’espace client dans le cadre de la maintenance WordPress et WooCommerce.
Les extraits de cet article restent compatibles avec PHP 7.4, le minimum exigé par WordPress 7.1 et WooCommerce, même si WordPress recommande PHP 8.3 ou plus.
Questions fréquentes sur la page de connexion WooCommerce
En résumé : partez de la page Mon compte, ajoutez du contenu par les hooks, surchargez form-login.php seulement si la structure doit changer, et posez des conditions dans vos redirections. La page de connexion séparée reste l’exception, et elle doit être exclue du cache.
Votre espace client demande davantage, par exemple des champs d’inscription propres à votre activité ou des onglets reliés à un outil externe ? Vous pouvez faire développer un espace client WooCommerce sur mesure.
Mis à jour en octobre 2026 par un développeur WordPress freelance senior.