En bref
Les assets « lourds » d’une scène (modèles.glb, textures, images de template, vidéos, PDF) ne sont pas embarqués en dur dans l’app open. Ils sont servis depuis un CDN Cloudflare (R2 public), résolus au runtime par le helper asset() de @wrappy/core.
Deux familles d’assets, à ne pas confondre :
Cette page couvre la première famille. L’UGC par invitation passe par le module
storage de l’API et le champ attachments du payload.
Le schéma de versionning
L’URL d’un asset template suit toujours cette forme :namespace= la scène (ou le composant partagé) propriétaire de l’asset. C’est le slug de la scène :fete-des-laurens,web-form,3d-book,gift-physics…version=v1,v2… versionnée par namespace (voir plus bas). Chaque scène évolue à son rythme.chemin= le chemin de l’asset dans son dossier (/models/x.glb,/images/ticket.png).
Le versionning est par namespace, pas global. Changer un asset de
web-form bumpe
web-form en v2 sans toucher fete-des-laurens, qui reste en v1.Pourquoi versionner
Les dossiers publiés sont immuables : on ne réécrit jamais unvN déjà en ligne. Une invitation déjà envoyée a été buildée avec VITE_ASSET_BASE_URL pointant sur une version donnée — si on écrasait les assets, elle changerait d’apparence après coup. Une révision d’asset = nouveau dossier v2, l’ancien continue de vivre.
Comment ça marche
Le helper asset()
packages/core/src/lib/assets.ts :
VITE_ASSET_BASE_URL= la racine CDN, sans version (ex:https://cdn.wrappy.app/templates/scenes). La version n’est pas dans l’env var — elle vit dansVERSIONS.VERSIONS= la table qui fixe la version courante de chaque namespace. C’est le seul endroit à toucher pour bumper.
Dev vs prod : même structure
En dev,VITE_ASSET_BASE_URL est vide → CDN_ROOT retombe sur /templates/scenes, servi statiquement par Vite depuis apps/open/public/.
Le dossier public/ est organisé exactement comme le CDN : dev et prod résolvent le même chemin, aucune divergence.
Développer une scène : utiliser asset()
1
Ranger les fichiers dans public/
Place tes assets sous
apps/open/public/templates/scenes/<ns>/v1/…, en gardant une arborescence lisible (/models, /images, /videos).2
Déclarer le namespace dans VERSIONS
Ajoute une entrée dans
VERSIONS (packages/core/src/lib/assets.ts) :Si le namespace est absent de
VERSIONS, asset() retombe sur v1 par défaut — mais déclare-le explicitement pour pouvoir le bumper plus tard.3
Référencer via asset() dans la scène
Ne mets jamais de chemin d’asset en dur. Passe toujours par
asset(namespace, path) :4
Tester en dev
bun run dev et vérifie que l’asset charge (onglet Network → 200 sur /templates/scenes/ma-scene/v1/…). Comme public/ reflète le CDN, ce qui marche en dev marchera en prod.Assets partagés entre scènes
Si un composant est réutilisé par plusieurs scènes (ex: le livre 3D3DBook, embarqué par fete-des-laurens et web-form), ses assets vivent sous son propre namespace (3d-book), pas dupliqués sous chaque scène :
Bumper un asset (nouvelle version)
Quand tu modifies un asset déjà publié en prod :1
Créer le nouveau dossier de version
Copie les assets du namespace sous
…/<ns>/v2/… dans public/templates/scenes/. Ne touche pas au dossier v1.2
Bumper VERSIONS
asset("ma-scene", …) pointent maintenant sur v2. Aucun autre changement de code.3
Publier sur le CDN
Voir la section suivante. Le
v1 reste en ligne pour les invitations déjà buildées.Publier sur le CDN
Le scriptscripts/upload-scene-assets.sh est un miroir récursif de public/templates/scenes/ vers le bucket R2 public :
templates/scenes/<ns>/<version>/…) via wrangler. Comme les dossiers de version sont immuables, republier ne réécrit que ce qui a changé (les nouveaux vN).
Côté build de open, poser :
VITE_ASSET_BASE_URL est une variable build-time de Vite (préfixe VITE_),
injectée via un ARG/ENV dans apps/open/Dockerfile. Elle est figée au build.Ce qui reste hors CDN
Les petits assets non liés à une scène restent servis par l’app depuispublic/ (à la racine, pas sous templates/scenes/) : logos, favicon, manifest.json, sons courts (page-flip.mp3), image OG de fallback. Trop petits pour justifier le détour CDN.
Récap
- Un asset de scène =
asset(namespace, path), jamais un chemin en dur. namespace= slug de la scène ;path= chemin dans son dossier.- La version vit dans
VERSIONS(packages/core/src/lib/assets.ts), par namespace. public/templates/scenes/reflète le CDN à l’identique → dev == prod.- Bump = nouveau dossier
vN+ mise à jour deVERSIONS, jamais d’écrasement. - Publication =
scripts/upload-scene-assets.sh.