#Journal des changements
Ce que la plateforme a gagné, perdu ou corrigé, à la date où c’est arrivé. Les entrées sont tirées de l’historique du dépôt, pas d’une feuille de route : chacune correspond à du code qui tourne.
#Ce que ce journal couvre
Trois choses, et rien d’autre :
- le format des thèmes — ce qu’un thème peut lire, écrire et rendre ;
- le CLI — ses commandes, ses options, ses confirmations ;
- l’API HTTP — ses routes, ses portées, ses codes d’erreur.
Ce qui bouge dans le CMS lui-même — l’interface, la facturation, l’assistant — n’y figure que si un développeur peut s’en apercevoir depuis son éditeur.
Webcosa est un service : il n’existe qu’une version en ligne, celle d’aujourd’hui. Un thème n’épingle donc pas une version du format, et il n’y a rien à mettre à jour. En contrepartie, ce journal est le seul endroit qui dise ce qui a changé sous les pieds d’un thème déjà écrit — les entrées marquées rupture sont celles qui demandent une action.
#5 octobre 2026
Aucune rupture. Un thème qui ne déclare ni templates/blog.json ni
templates/article.json — c’est le cas des huit thèmes d’origine — rend
exactement comme avant, blog compris.
#Des sections écrites par Cosa
L’éditeur de thème sait faire écrire par Cosa une section que le thème n’a
pas. Elle arrive dans le thème comme un fichier sections/genere-<nom>.liquid,
ouvert par un commentaire de provenance, aux styles tous rangés sous
#cosa-{{ section.id }} et sans JavaScript. Rien ne change pour un thème
existant ; si tu en trouves un dans un thème que tu maintiens, c’est une
section comme une autre. Voir Les sections.
#Le blog, rendu par le thème
Deux gabarits de plus, au modèle de Shopify : templates/article.json rend un
article (/blog/<blog>/<article>), templates/blog.json les listes (/blog
et /blog/<blog>). Avec eux, deux objets : article
— titre, extrait, adresse, image, date, contenu et son blog — et
blog — titre, description, adresse, articles,
blogs. Ils n’existent que sur ces vues.
Jusqu’ici, le blog était toujours servi dans la page de la plateforme : sans
l’en-tête, le menu, le pied ni les polices du thème. C’est encore le cas quand
le gabarit manque, et il n’y a pas de repli sur page.json : c’est le
fichier qui décide. Voir Les templates.
#L’éditeur de code du CMS souligne ce qui casse en silence
« Modifier le code » d’un thème passe à un vrai éditeur : complétion des objets,
des filtres et des tags que le moteur connaît — et des id du {% schema %}
après section.settings., des réglages globaux après settings., des snippets
après {% render ' —, multi-curseur, repli, mise en forme du JSON.
Il vérifie pendant qu’on tape, avec la même analyse qu’à l’enregistrement, et
signale ce que le moteur laisse passer sans un mot : un filtre ou un objet de
Shopify (les absents), un réglage lu mais jamais déclaré, un
snippet ou une section qui n’existe pas, 'assets/theme.css' | asset_url, un
type de réglage inconnu, un <script> en ligne, une police ou une image
d’un autre domaine. Rien ne change pour un thème déjà écrit : ce sont des
avertissements, et l’enregistrement ne refuse toujours que les erreurs de
syntaxe (les fichiers).
L’assistant du CMS s’y ouvre aussi : il explique un fichier, corrige un problème souligné ou modifie une sélection, et propose chaque changement en différence, à accepter morceau par morceau. Il n’écrit et n’enregistre rien lui-même.
#Les photos retaillées gardent leurs proportions
Depuis le 1er octobre, les photos de la médiathèque servies en plusieurs
largeurs (srcset) étaient recadrées en une tranche verticale, puis étirées :
elles paraissaient zoomées sur un détail. Elles sont de nouveau réduites à
leurs proportions d’origine. Rien à changer dans un thème.
#Les liens internes d’un article
Dans article.contenu, un lien vers une autre page du site (une adresse qui
commence par /) est désormais un lien ordinaire. Il sortait en
rel="noopener nofollow" et dans un nouvel onglet, comme un lien externe :
Google ne suivait pas le maillage interne de l’article. Les liens vers
d’autres sites, eux, ne changent pas.
#Les robots d’IA et llms.txt, site par site
Chaque site client sert désormais un /llms.txt : sa fiche (adresse,
téléphone, horaires de Paramètres › Coordonnées), ses pages publiées et ses
articles, aux adresses canoniques. Il répond 404 si le site est protégé par un
code, masqué des moteurs ou sans page publiée.
Son robots.txt ne change pas d’un octet tant que le client laisse la
plateforme décider. Depuis l’écran Agentique du CMS, il peut fermer
ChatGPT, Perplexity, Claude, Gemini ou l’entraînement des modèles : leurs
robots reçoivent alors un groupe Disallow: / à part, et les autres
continuent de lire User-agent: *. Côté API, l’onglet ia de
/api/parametres/<onglet> porte ce réglage — voir Atelier.
Rien à changer dans un thème : ces fichiers sont posés par la plateforme,
comme le plan du site.
Le même jour, le llms.txt s’est enrichi de ce que le client écrit dans
l’écran Agentique : son métier (une ligne Activité), la date de la
dernière mise à jour du contenu (Mis à jour le : AAAA-MM-JJ), et une section
## Questions fréquentes — ses questions-réponses validées, une ### par
question, placée avant les listes de liens. Aucune n’y entre sans sa
validation, et rien de tout cela ne paraît sur ses pages : pour les montrer, il
pose une section de questions fréquentes — qui donne alors aussi à la page ses
données structurées FAQPage, puisqu’elles y sont visibles. Rien à changer
dans un thème.
#siAbsent : écrire un fichier sans jamais en écraser un
PUT /api/themes/<id>/fichiers accepte un champ facultatif siAbsent. Avec
lui, un chemin déjà pris par un autre contenu répond 409 fichier_existe, et
le même contenu répond 200 sans rien écrire. Sans lui, rien ne change : le
PUT remplace. C’est ce qu’emploie Cosa pour ajouter une section à un thème.
Voir Fichiers.
#garde : n’écrire que sur ce qu’on a lu
PATCH /api/menus et PATCH /api/parametres/<onglet> remplacent l’objet
entier. Ils acceptent désormais un champ facultatif
garde: { site, majLe } — l’identifiant du site visé et l’updated_at lu
avant d’écrire (null si l’objet n’existait pas). Si le site courant n’est
pas celui-là, la route répond 409 autre_site ; si l’objet a changé depuis,
409 modifie_entre_temps — et rien n’est écrit. Sans garde, rien ne change.
C’est ce qu’emploient les propositions de Cosa, qui peuvent être confirmées
longtemps après avoir été calculées. Voir Atelier.
#Du 7 au 11 août 2026
Aucune rupture. Tout ce qui suit est un ajout : un thème écrit avant ces dates rend exactement comme avant, et n’a rien à reprendre.
#Les polices, servies par la plateforme
10 août. Un quatorzième type de réglage, font_picker. Sa valeur est
l’identifiant d’une famille du catalogue de la plateforme — dix-neuf, servies
depuis /polices/ — ou systeme, qui n’en télécharge aucune. Le thème
nomme une police, il ne la transporte pas : assets/ n’accepte toujours
que .css et .svg.
Deux filtres maison vont avec, et il faut les deux.
<style>
{{ settings.police_titres | font_face }}
</style>
{%- assign pile_titres = settings.police_titres | font_famille -%}
--titre-police: {% if pile_titres != blank %}{{ pile_titres }}{% else %}var(--texte-police){% endif %};font_face écrit la règle @font-face — le fichier, les graisses,
font-display: swap ; font_famille rend la pile complète, la famille puis
son repli système. Un identifiant hors catalogue rend une chaîne vide,
jamais une erreur — et c’est par là que passe systeme : le thème teste
!= blank et pose le repli qu’il veut, comme ci-dessus.
#Les éditions
7 août avec Aplomb, généralisées le 11. config/theme.json accepte un
tableau editions : plusieurs habillages complets du même thème, chacun ne
posant que des valeurs de réglages — jamais une structure, jamais une
section, jamais un gabarit. Depuis le 11 août, une édition peut aussi
déclarer les metiers auxquels elle va, ce qui relie l’habillage au
contenu dans l’aperçu du Store. Le tableau editions lui-même reste
facultatif : un thème sans édition s’installe avec ses réglages par
défaut, comme avant. Voir Ajouter un thème au catalogue.
#Quatre thèmes d’origine de plus
Aplomb le 7 août, puis Cadence, Épure et Scène le 10. Le catalogue en compte huit.
#5 août 2026
La journée où la plateforme est devenue programmable. Tout ce qui suit est arrivé le même jour, dans cet ordre.
#Les thèmes Liquid
Un site peut désormais être rendu par un thème au format Shopify plutôt que
par les composants React du CMS. Six dossiers, layout/theme.liquid comme
coquille, des sections déclarées par un bloc {% schema %}, et des templates
JSON qui les composent.
layout/ .liquid
sections/ .liquid
snippets/ .liquid
assets/ .css .svg
config/ .json
templates/ .jsonLes deux moteurs cohabitent, et c’est délibéré. Un site qui a un thème publié passe par Liquid ; tous les autres continuent exactement comme avant. Aucun site en ligne n’a changé d’apparence ce jour-là — c’est ce qui a permis d’installer les thèmes sans fenêtre de maintenance. Voir l’anatomie d’un thème.
#Quatre thèmes d’origine
Origo d’abord : trente-cinq sections, sept gabarits de page, et de quoi tout régler sans toucher au code — couleurs, typographie, arrondi, largeur, densité. C’est le thème que reçoit tout le monde. Puis Forge, Vela et Piazza, plus typés.
Ils ont été renommés le jour même : leurs premiers noms étaient français et ne se prononçaient nulle part ailleurs. Un thème est un objet de catalogue, il voyage.
#page.demande — remercier sans JavaScript
Le formulaire de contact des thèmes postait dans le vide : il avait l’air de marcher et n’enregistrait rien. Il enregistre maintenant, et la page se rend à nouveau avec un objet de plus :
{% if page.demande == 'merci' %}
<p class="merci">Merci, votre message est parti.</p>
{% elsif page.demande == 'erreur' %}
<p class="erreur">L’envoi a échoué. Réessayez dans un instant.</p>
{% endif %}La valeur est lue dans la chaîne de requête après la redirection. C’est ce qui
permet à une section de remercier sans une ligne de script — et c’est cohérent
avec le refus du .js dans assets/.
#Le bac à sable prend ses bornes
Un thème s’exécute sur le serveur qui rend aussi les sites de tous les autres. Quatre bornes sont posées : rendu plafonné à 3 secondes, source analysée à 512 Ko, objets créés à 10⁸, imbrication de sections à 6 niveaux.
Deux détails valent d’être connus, parce qu’ils viennent de défauts réels :
- les 3 secondes sont appliquées deux fois. Une simple course contre un minuteur ne coupait rien : un rendu synchrone bloque le fil d’exécution de Node, donc le minuteur ne s’exécutait jamais ;
- le compteur de profondeur vit dans une fermeture, hors de portée du
thème. Tant qu’il vivait dans le contexte Liquid,
{% assign _profondeur = 0 %}suffisait à le remettre à zéro — un compteur qui surveille du code ne doit pas être écrit par ce code.
Le détail complet est sur la page du bac à sable.
#asset_url ne trouvait aucune feuille de style
Rupture — c’est le correctif qui demande peut-être une action de ta part.
Le filtre ajoutait le segment assets/ à l’adresse qu’il produisait, alors que
la route des fichiers de thème n’en veut pas :
| Adresse produite | |
|---|---|
| Avant | /theme-assets/<id>/assets/theme.css — 404 |
| Après | /theme-assets/<id>/theme.css |
La route est /theme-assets/<id>/<fichier>, un seul segment de nom, et c’est
elle qui remet le préfixe assets/ pour interroger la base. Conséquence :
aucun site sur thème Liquid n’avait jamais chargé sa feuille de style depuis
que les thèmes existaient. Le défaut ne levait aucune erreur — la page rendait
quand même, en HTML nu, ce qui ressemble à un thème mal écrit plutôt qu’à une
adresse fausse.
asset_url prend le nom seul du fichier, jamais son chemin.
{{ 'theme.css' | asset_url | stylesheet_tag }}Si un thème écrit {{ 'assets/theme.css' | asset_url }}, il fabrique
maintenant une adresse à deux segments qui ne correspond à aucune route :
retire le préfixe. Voir la page des assets.
#Le CLI
scripts/theme.mjs transporte les fichiers d’un thème entre un dossier local et
un site. Node 20.13 ou plus, aucune dépendance, un seul fichier qu’on peut
copier
ailleurs que dans ce dépôt.
node scripts/theme.mjs connexionnode scripts/theme.mjs recuperer --theme=Atelier --dossier=~/themes/ateliernode scripts/theme.mjs suivreSix commandes — connexion, lister, recuperer, pousser, suivre,
publier — chacune avec un alias anglais. Trois garde-fous qui n’ont pas été
ajoutés après coup :
poussersignale les fichiers distants absents en local, il ne les supprime pas.--supprimerles retire, après les avoir listés et demandé confirmation ;recupererliste les fichiers locaux divergents avant de les écraser ;suivrerefuse un thème publié sans--oui-je-sais, et propose de le dupliquer.
Il n’y a pas de serveur d’aperçu local, et il n’y en aura pas : la raison tient en trois paragraphes. Référence complète des commandes sur cette page.
#Les clés d’API
Le CLI ne connaît pas les cookies du navigateur : il s’authentifie avec une clé,
créée dans le CMS sous Paramètres → Clés d’API. Deux portées seulement —
lecture pour lire, themes pour tout.
Le secret (wc_ suivi de 43 caractères) ne s’affiche qu’une fois. La base
n’en garde que l’empreinte : personne, pas même nous, ne peut le rendre. Une clé
perdue se révoque et se remplace.
Le site visé se désigne par l’en-tête X-Webcosa-Site-Cible. Le suffixe
-Cible n’est pas décoratif : X-Webcosa-Site, sans lui, est un en-tête que le
proxy pose lui-même et purge de toute requête entrante. L’envoyer revient à
ne rien envoyer, et à écrire dans le premier site venu. Voir
l’authentification.
#L’éditeur de code, dans le CMS
Les fichiers d’un thème s’éditent aussi depuis le navigateur, avec la coloration
syntaxique et le refus de supprimer les trois fichiers indispensables
(layout/theme.liquid, templates/index.json, config/settings_schema.json).
C’est le chemin du dépannage, pas celui du travail quotidien : le CLI garde ton Git, tes raccourcis et ton éditeur. Les deux écrivent dans la même table.
#Le Store prend son adresse
Le catalogue des thèmes vit désormais sur store.webcosa.com, servi par le même
déploiement mais sur son propre hôte — et ouvert aux moteurs de recherche.
Ajouter un thème au catalogue passe par
le guide dédié ; rien n’y monte automatiquement depuis un
site.
#Cette documentation
dev.webcosa.com : les pages de référence et les guides, la recherche en
⌘K, et un bouton « Copier la page » qui rend le markdown de la page pour le
coller dans un assistant.
Deux écarts ont été relevés en l’écrivant, et documentés tels quels plutôt que corrigés en silence :
theme_basecommentaire de codeLe commentaire annonçait une base /t/<theme> ; la vraie base est
/theme-assets/<id>, et /t/… n’existe nulle part. C’est la première ligne
qu’on lit en enquêtant sur un 404 d’asset_url — elle envoyait chercher une
route absente.
TAILLE_MAX524288Comparé à la longueur de la chaîne, donc à des unités de code UTF-16, pas à
des octets. Un fichier plein d’accents passe la barre un peu plus tard qu’un
ls -l ne le laisse croire. Sans conséquence pratique : la borne existe pour
arrêter une archive malveillante, pas pour discipliner une feuille de style.
#Avant le 5 août 2026
Rien à signaler ici, et c’est exact : il n’y avait pas de surface développeur. Les sites étaient rendus par les composants React du registre du CMS, réglés depuis l’éditeur visuel. Aucun thème, aucun Liquid, aucune API publique, donc rien qu’un thème écrit aujourd’hui puisse regretter.
Ces sites-là existent toujours et continuent de rendre comme avant. C’est ce que recouvre l’expression « les deux moteurs » dans le reste de la documentation : un site passe par Liquid le jour où on lui publie un thème, jamais avant.
Tu as trouvé un comportement qui contredit une page de cette documentation ?
C’est un défaut, et il se corrige dans les deux sens — soit le code, soit la
page. Écris à bonjour@webcosa.com avec l’adresse de la page.

