← Dossiers · Plugin sur-mesure
L'app Shopify qui n'existait pas — construire un personalizer broderie maison
Sur Shopify, personnaliser un produit reste un problème ouvert. Récit d'un personalizer broderie en Canvas 2D — variants, upsells, cart line properties, et un audit de migration Horizon → Dawn.
Publié le
Sommaire
Sur Shopify, personnaliser un produit reste un problème ouvert. L’écosystème des apps de personnalisation existe, mais chaque solution généraliste arrive avec son lot d’arbitrages qui finissent par contraindre la marque : rendu standardisé, intégration thème imposée, abonnement mensuel qui grimpe avec les commandes, dépendance à un éditeur tiers. Pour un site dont l’identité visuelle repose précisément sur la qualité du rendu de personnalisation, ces arbitrages deviennent vite des goulots.
Création Personnalisée vend de la broderie sur textile : tabliers, sacs, peignoirs, doudous, linge de maison. Le cœur de l’offre, c’est la personnalisation — un prénom brodé sur un peignoir bébé, une initiale sur un sac de plage, un message court sur un tablier. L’utilisateur tape son texte, choisit la police, la couleur de fil, et doit pouvoir voir, avant de commander, ce qu’il va recevoir. Pas une approximation. Pas un rendu schématique. Quelque chose d’assez fidèle pour que le client visualise la broderie réelle et clique « ajouter au panier » sans appréhension.
Ce dossier raconte la construction d’un personalizer maison directement intégré au thème, en JavaScript vanilla et Canvas 2D, dans sa version stabilisée 3.2 sur le thème Horizon. Et le travail parallèle d’audit de migration vers Dawn, le thème de référence Shopify.
Le contexte — pourquoi pas une app du store Shopify
Le Shopify App Store propose plusieurs solutions de personnalisation de produit. Elles couvrent bien les cas simples — une zone de texte, une couleur, un upload d’image — mais s’effondrent dès qu’on veut sortir du path heureux du SaaS générique.
Trois limites observées en pratique sur Création Personnalisée :
-
Le rendu visuel est standardisé. Les apps généralistes affichent le texte personnalisé en surimpression simple sur l’image produit, sans tentative de simulation du grain de la broderie. Pour un site dont l’argument commercial est précisément la qualité du rendu brodé, ce contraste entre la prévisualisation et le livrable réel devient un problème de confiance.
-
L’intégration au thème impose son moule. Les apps Shopify s’injectent généralement via une
app blockou un script global qui surcharge la page produit. Le résultat tient debout mais ne se fond pas dans la grille typographique du thème, ne suit pas les conventions de spacing du gabarit produit, et coupe régulièrement la navigation au clavier ou les animations de scroll. -
Le pricing scale avec les commandes. À 19 €/mois pour les plans d’entrée, puis 49 € puis 99 € quand les fonctionnalités s’ajoutent — multiplié par 12 mois, ça représente assez vite plus que le coût d’un développement maison amorti.
La décision a été prise il y a un peu plus d’un an : sortir du modèle SaaS, et coder le personalizer dans le thème, en code propre, versionné, propriété de la marque. Avec une cible de raffinement progressif sur 18 mois, version après version. La 3.2 est l’état stabilisé d’aujourd’hui.
Le défi technique — simuler de la broderie en Canvas 2D
La broderie n’est pas un effet typographique standard. Quand on tape un prénom dans Photoshop et qu’on le pose en blanc sur du tissu, on obtient un texte plat — pas une broderie. La broderie réelle a du relief, de la matière, des bords légèrement irréguliers, et capte la lumière différemment selon l’orientation du point.
L’approche naïve aurait été de fournir des assets pré-rendus pour chaque prénom courant. Inutilisable : trop limité, et ça force l’utilisateur à se conformer à une liste de prénoms.
L’approche choisie : générer le rendu en temps réel via Canvas 2D côté navigateur, en superposant plusieurs effets sur le <canvas> pour approcher visuellement la broderie. Trois ingrédients superposés :
ctx.fillText()pour poser la lettre en couleur de filctx.shadowOffsetX/Ypour donner une légère profondeur — pas une drop shadow agressive, juste un décalage de 1 à 2 pixels avec une opacité maîtrisée pour simuler le relief du point- Une variation de la
lineWidthdu contour pour casser la régularité parfaite d’un rendu vectoriel et suggérer le grain de la broderie
C’est une simplification — ce n’est pas du chain-stitch simulé point par point comme certaines apps haut de gamme savent le faire. Mais c’est suffisamment fidèle pour que l’utilisateur reconnaisse une broderie, et largement plus juste qu’un texte plat en surimpression. Le compromis tient parce qu’il est honnête : la page produit indique clairement « prévisualisation à titre indicatif », et la photographie produit montre des exemples de broderie réelle à côté.
Tout est fait côté client. Aucun appel API, aucune dépendance externe. Le <canvas> est rafraîchi à chaque keystroke ou changement de variant, avec un requestAnimationFrame pour éviter de saturer le thread principal sur les machines modestes.
L’architecture v3.2 — zones de texte, positionnement et variants
Le personalizer est organisé autour d’une notion de zone de texte intelligente. Chaque produit broderie dispose d’une zone définie par quatre coordonnées en pourcentage relatif à l’image produit :
const textZone = {
topPct: 0.42,
leftPct: 0.28,
widthPct: 0.44,
maxLines: 2,
};
Le pourcentage plutôt que le pixel absolu rend la zone robuste à toutes les tailles d’écran et à tous les zooms responsive. Quand le <canvas> est redimensionné — au resize fenêtre, à la rotation d’un mobile — la zone est recalculée automatiquement à partir des dimensions actuelles. Pas de positionnement absolu qui se décale, pas de breakpoint à maintenir manuellement.
Le texte saisi est fitted dans cette zone : si l’utilisateur tape un prénom long, la fonte est réduite progressivement, puis le texte passe en deux lignes si la zone le permet, puis tronque proprement si même deux lignes ne suffisent pas. Une helper fitTextInZone() fait ce calcul une seule fois par render, en partant de la fonte la plus large et en réduisant par paliers de 2 px jusqu’à trouver un fit valide.
Au-dessus du <canvas>, le variant picker présente les choix sous forme de pills, pas de menus déroulants. Couleur de fil, police de broderie, position de l’inscription — chaque option est une pastille cliquable avec un état actif visuellement clair. Sur mobile, ces pills passent en scroll horizontal pour rester sur une seule ligne sans casser la grille de la page produit.
Quand l’utilisateur clique « ajouter au panier », les paramètres de personnalisation sont attachés à la ligne de panier via les cart line item properties, le mécanisme natif Shopify pour transporter des metadata non-standardisées avec un produit :
const formData = new FormData();
formData.append('id', variantId);
formData.append('quantity', '1');
formData.append('properties[Prénom]', userInput);
formData.append('properties[Couleur fil]', selectedThread);
formData.append('properties[Police]', selectedFont);
formData.append('properties[_render_hash]', renderHash);
Le préfixe underscore (_render_hash) est une convention Shopify : les properties qui commencent par _ ne sont pas affichées au client dans son panier, mais sont conservées et visibles dans l’admin Shopify. C’est utilisé ici pour stocker un hash de la combinaison rendue, qui permet plus tard de retrouver précisément le rendu prévisualisé par le client si l’atelier broderie a un doute sur le visuel attendu.
Les upsells — toggle avant l’add to cart
Au-dessus du bouton « ajouter au panier », un bloc d’upsell propose des compléments cohérents avec la commande : pochette cadeau, étiquette personnalisée, broderie d’une initiale sur le côté. Chaque upsell est un toggle, pas un produit séparé à ajouter au panier. Le toggle affecte directement le variant du produit principal ou ajoute des line items invisibles côté front avec leurs propres properties.
Cette approche évite trois écueils classiques de l’upsell en e-commerce :
- Pas de pop-up after-add-to-cart qui casse le flow et augmente l’abandon
- Pas de produit séparé que le client peut supprimer du panier en pensant que c’est une erreur
- Pas de bundle pricing à expliquer — le prix total se met à jour en clair sous le bouton
Le taux d’attache des upsells a doublé sur les deux mois suivant le déploiement de la 3.0, comparé à la solution app du store qu’utilisait précédemment Création Personnalisée. La cause probable : la friction réduite. Le client voit l’upsell, le coche s’il veut, et passe au panier sans interruption.
L’audit Horizon → Dawn
Au milieu du chantier 3.x, Shopify a annoncé que Dawn restait la référence pour les futurs développements et que Horizon, hérité d’une période antérieure, n’allait plus recevoir les mises à jour structurelles des nouveaux paradigmes Shopify (les theme app extensions, les sections everywhere, le futur editor 2.0).
Question posée : faut-il migrer ?
J’ai produit un audit de migration documenté, ~30 pages, qui inventorie pour chaque morceau du personalizer son équivalent ou son décalage sur Dawn. Trois conclusions principales :
-
Le cœur Canvas 2D est portable sans modification. C’est du JS vanilla qui ne dépend d’aucune primitive du thème. La couche de prévisualisation peut basculer en l’état.
-
L’intégration au gabarit produit demande un refactor. Horizon utilise une architecture de sections relativement classique. Dawn pousse davantage sur les blocks configurables par le marchand et les theme blocks hérités d’une section parente. Le code Liquid actuel du personalizer doit être réécrit en respectant ces conventions, sinon on perd l’éditabilité côté Shopify Admin.
-
Les variant pickers sont à reconstruire. Dawn impose ses propres conventions de presentation des variants — composants
<variant-picker>Web Components natifs, événementsvariant:changestandardisés. Forcer le picker actuel à coexister avec ceux de Dawn créerait des conflits d’événements.
L’estimation de l’effort : entre 8 et 14 jours pour une migration propre. Le client a choisi de reporter au prochain trimestre, en attendant que la roadmap commerciale soit consolidée. L’audit reste sur la table — un dossier prêt à exécuter au moment opportun, qui évite de redécouvrir les enjeux dans six mois.
Ce que ce projet apprend
Trois choses tiennent à l’usage.
Construire dans le thème reste sous-coté sur Shopify. L’écosystème pousse fort vers les apps, le marketplace, la mensualisation. Mais pour les fonctionnalités structurantes d’une marque — celles qui sont l’argument commercial, pas un complément — coder dans le thème reste l’option la plus durable. Pas de dépendance éditeur, pas d’augmentation de prix annuelle, pas de risque qu’une mise à jour de l’app casse votre tunnel à 23 h un samedi soir. Le code appartient au marchand, est versionné dans son repo, et peut être audité comme n’importe quel code produit.
Le Canvas 2D suffit largement pour de la simulation honnête. On n’est pas obligé d’aller chercher WebGL ou Three.js dès qu’on parle rendu produit. Pour 90 % des besoins de prévisualisation de personnalisation, le Canvas 2D avec quelques effets composés rend très bien — et tourne sans broncher sur le smartphone d’entrée de gamme de quelqu’un qui regarde votre site dans le métro.
Un audit de migration vaut son coût même s’il ne déclenche pas la migration. Le doc Horizon → Dawn n’a pas (encore) été exécuté. Mais sa simple existence permet au client de décider en connaissance de cause : pas de migration tant que la roadmap commerciale n’est pas claire, et quand elle le sera, l’estimation est déjà là. Pas besoin de redémarrer la réflexion. C’est typiquement le genre de livrable qui paraît sec sur le coup et qui paye dix-huit mois plus tard.
Le personalizer continue d’évoluer — la 3.3 doit introduire un sélecteur de polices avec preview en temps réel sur chacune. Le chantier s’étire dans le temps parce qu’il fait gagner de l’argent à chaque version, pas parce qu’il faut « finir » quelque chose.