[{"data":1,"prerenderedAt":605},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs\u002Fexisting-app":137},[4],{"title":5,"path":6,"stem":7,"children":8,"page":44},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,45,66,95,116],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"App Nuxt existante","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F03.cli",{"title":28,"path":29,"stem":30,"children":31,"page":44},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[32,36,40],{"title":33,"path":34,"stem":35},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":37,"path":38,"stem":39},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":41,"path":42,"stem":43},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",false,{"title":46,"path":47,"stem":48,"children":49,"page":44},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[50,54,58,62],{"title":51,"path":52,"stem":53},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":55,"path":56,"stem":57},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":59,"path":60,"stem":61},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":63,"path":64,"stem":65},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":67,"path":68,"stem":69,"children":70,"page":44},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[71,75,79,83,87,91],{"title":72,"path":73,"stem":74},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":76,"path":77,"stem":78},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":80,"path":81,"stem":82},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":84,"path":85,"stem":86},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":88,"path":89,"stem":90},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":92,"path":93,"stem":94},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":96,"path":97,"stem":98,"children":99,"page":44},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[100,104,108,112],{"title":101,"path":102,"stem":103},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":105,"path":106,"stem":107},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":109,"path":110,"stem":111},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":113,"path":114,"stem":115},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":117,"path":118,"stem":119,"children":120,"page":44},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[121,125,129,133],{"title":122,"path":123,"stem":124},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":126,"path":127,"stem":128},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":130,"path":131,"stem":132},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":134,"path":135,"stem":136},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"id":138,"title":20,"body":139,"description":600,"extension":601,"meta":602,"navigation":317,"path":21,"seo":603,"stem":22,"__hash__":604},"docs_fr\u002Ffr\u002Fdocs\u002F02.existing-app.md",{"type":140,"value":141,"toc":593},"minimark",[142,147,169,174,185,267,282,379,385,393,417,428,432,435,518,521,525,555,559,571,577,581,589],[143,144,146],"h1",{"id":145},"ajouter-fougere-à-une-app-nuxt-existante","Ajouter Fougere à une app Nuxt existante",[148,149,150,151,155,156,159,160,164,165,168],"p",{},"Fougere ajoute sa couche modèle à l'app existante. Le routing, les pages, les composants,\nle style et les routes serveur restent en place. Le module enregistre uniquement ses\npropres chemins : ",[152,153,154],"code",{},"\u002F_fougere\u002Fcall","\n(l'enveloppe), ",[152,157,158],{},"\u002Fapi\u002F{frond}\u002F…"," (",[161,162,163],"a",{"href":127},"surface REST",") et ",[152,166,167],{},"\u002Fauth\u002F**","\nsi vous activez l'auth.",[170,171,173],"h2",{"id":172},"les-trois-pièces","Les trois pièces",[148,175,176,180,181,184],{},[177,178,179],"strong",{},"1. Le module"," — dans votre ",[152,182,183],{},"nuxt.config.ts"," existant :",[186,187,192],"pre",{"className":188,"code":189,"language":190,"meta":191,"style":191},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","export default defineNuxtConfig({\n  modules: [\u002F* vos modules *\u002F, '@fougere\u002Fnuxt'],\n});\n","ts","",[152,193,194,218,255],{"__ignoreMap":191},[195,196,199,203,206,210,214],"span",{"class":197,"line":198},"line",1,[195,200,202],{"class":201},"sVHd0","export",[195,204,205],{"class":201}," default",[195,207,209],{"class":208},"sGLFI"," defineNuxtConfig",[195,211,213],{"class":212},"su5hD","(",[195,215,217],{"class":216},"sP7_E","{\n",[195,219,221,225,228,231,235,238,242,246,249,252],{"class":197,"line":220},2,[195,222,224],{"class":223},"skxfh","  modules",[195,226,227],{"class":216},":",[195,229,230],{"class":212}," [",[195,232,234],{"class":233},"sutJx","\u002F* vos modules *\u002F",[195,236,237],{"class":216},",",[195,239,241],{"class":240},"sjJ54"," '",[195,243,245],{"class":244},"s_sjI","@fougere\u002Fnuxt",[195,247,248],{"class":240},"'",[195,250,251],{"class":212},"]",[195,253,254],{"class":216},",\n",[195,256,258,261,264],{"class":197,"line":257},3,[195,259,260],{"class":216},"}",[195,262,263],{"class":212},")",[195,265,266],{"class":216},";\n",[148,268,269,272,273,276,277,281],{},[177,270,271],{},"2. La config"," — ",[152,274,275],{},"fougere.config.ts"," à la racine\n(",[161,278,280],{"href":279},"\u002Ffr\u002Fdocs\u002Fgetting-started#fougereconfigts-r%C3%A9f%C3%A9rence","référence complète",") :",[186,283,285],{"className":188,"code":284,"language":190,"meta":191,"style":191},"import { defineFougere } from '@fougere\u002Fcore';\n\nexport default defineFougere({\n  db: { dialect: 'sqlite', path: '.data\u002Fapp.db' },\n});\n",[152,286,287,313,319,331,370],{"__ignoreMap":191},[195,288,289,292,295,298,301,304,306,309,311],{"class":197,"line":198},[195,290,291],{"class":201},"import",[195,293,294],{"class":216}," {",[195,296,297],{"class":212}," defineFougere",[195,299,300],{"class":216}," }",[195,302,303],{"class":201}," from",[195,305,241],{"class":240},[195,307,308],{"class":244},"@fougere\u002Fcore",[195,310,248],{"class":240},[195,312,266],{"class":216},[195,314,315],{"class":197,"line":220},[195,316,318],{"emptyLinePlaceholder":317},true,"\n",[195,320,321,323,325,327,329],{"class":197,"line":257},[195,322,202],{"class":201},[195,324,205],{"class":201},[195,326,297],{"class":208},[195,328,213],{"class":212},[195,330,217],{"class":216},[195,332,334,337,339,341,344,346,348,351,353,355,358,360,362,365,367],{"class":197,"line":333},4,[195,335,336],{"class":223},"  db",[195,338,227],{"class":216},[195,340,294],{"class":216},[195,342,343],{"class":223}," dialect",[195,345,227],{"class":216},[195,347,241],{"class":240},[195,349,350],{"class":244},"sqlite",[195,352,248],{"class":240},[195,354,237],{"class":216},[195,356,357],{"class":223}," path",[195,359,227],{"class":216},[195,361,241],{"class":240},[195,363,364],{"class":244},".data\u002Fapp.db",[195,366,248],{"class":240},[195,368,369],{"class":216}," },\n",[195,371,373,375,377],{"class":197,"line":372},5,[195,374,260],{"class":216},[195,376,263],{"class":212},[195,378,266],{"class":216},[148,380,381,384],{},[177,382,383],{},"3. Une première Frond"," — une entité et un handler, à la racine de l'app que vous avez\ndéjà :",[186,386,391],{"className":387,"code":389,"language":390},[388],"language-text","entities\u002FTodo.ts\nhandlers\u002FTodoHandler.ts\n","text",[152,392,389],{"__ignoreMap":191},[148,394,395,396,400,401,404,405,408,409,412,413,416],{},"Le scanner reconnaît ces deux fichiers grâce à la convention utilisée à la racine du\nprojet (",[161,397,399],{"href":398},"\u002Ffr\u002Fdocs\u002Fgetting-started#un-seul-domaine-pas-de-fronds-du-tout","la forme à plat",").\nUne page écrit\n",[152,402,403],{},"import Todo from '@frond\u002F\u003Cnom-de-votre-paquet>\u002Fentities\u002FTodo'"," — le module enregistre cet\nalias depuis le scan, donc il n'y a ni ",[152,406,407],{},"package.json"," ni entrée ",[152,410,411],{},"pnpm-workspace.yaml"," à\najouter. Un deuxième domaine ira plus tard dans ",[152,414,415],{},"fronds\u002Fbilling\u002F",", et ces deux fichiers ne\nbougent pas.",[148,418,419,420,423,424,427],{},"Lancez ",[152,421,422],{},"pnpm dev"," et vérifiez le log : ",[152,425,426],{},"scanned 1 frond(s)",".",[170,429,431],{"id":430},"migrer-feature-par-feature","Migrer feature par feature",[148,433,434],{},"Prenez une fonctionnalité à la fois ; les anciennes routes continuent de servir le reste.\nLes éléments suivants ont un équivalent Fougere :",[436,437,438,451],"table",{},[439,440,441],"thead",{},[442,443,444,448],"tr",{},[445,446,447],"th",{},"Ce que vous maintenez aujourd'hui",[445,449,450],{},"Ce que ça devient",[452,453,454,466,474,489,502],"tbody",{},[442,455,456,460],{},[457,458,459],"td",{},"un schéma Zod\u002FYup",[457,461,462,463],{},"les champs de l'entité — ",[161,464,465],{"href":52},"axe shape",[442,467,468,471],{},[457,469,470],{},"une définition de table ou une migration additive",[457,472,473],{},"dérivée — auto-DDL additif depuis les mêmes champs ; les changements destructifs restent explicites",[442,475,476,482],{},[457,477,478,481],{},[152,479,480],{},"server\u002Fapi\u002Ftodos.post.ts"," + appel de validation",[457,483,484,485,488],{},"une opération de ",[161,486,487],{"href":73},"handler",", validée à la façade",[442,490,491,494],{},[457,492,493],{},"l'état du formulaire + règles côté client",[457,495,496,501],{},[161,497,498],{"href":106},[152,499,500],{},"useFormFor(Todo)"," — même validation que le serveur",[442,503,504,510],{},[457,505,506,509],{},[152,507,508],{},"useFetch('\u002Fapi\u002Ftodos')"," + comptabilité de refresh",[457,511,512,517],{},[161,513,514],{"href":102},[152,515,516],{},"useQuery(Todo, 'list')"," — revalidée par les commands",[148,519,520],{},"Supprimez les originaux à chaque feature migrée — le but est d'avoir moins de fichiers à\nsynchroniser, pas une copie parallèle.",[170,522,524],{"id":523},"ce-qui-reste-à-vous","Ce qui reste à vous",[526,527,528,535,541],"ul",{},[529,530,531,534],"li",{},[177,532,533],{},"Pages et composants"," — les primitives sont additives ; pas de layout, pas de widgets.",[529,536,537,540],{},[177,538,539],{},"Les autres routes serveur"," — tout ce qui est hors des chemins revendiqués est intact.",[529,542,543,546,547,550,551,554],{},[177,544,545],{},"L'auth"," — optionnelle. Gardez votre système si vous en avez un ; ",[152,548,549],{},"useCurrentUser"," et\nle flux session→handler demandent l'",[161,552,553],{"href":110},"auth Fougere"," activée.",[170,556,558],{"id":557},"limites-actuelles","Limites actuelles",[526,560,561,568],{},[529,562,563,564,567],{},"Les paquets sont sur npm sous le tag ",[152,565,566],{},"alpha"," — le numéro de version est toute la\npromesse.",[529,569,570],{},"Le storage est SQLite auto-DDL (Kysely dessous). La table d'une entité appartient à\nFougere — migrez une feature quand vous pouvez lui confier son storage, gardez votre\naccès base existant pour le reste.",[148,572,573,574,576],{},"Suite : ",[161,575,24],{"href":25}," — composer un workspace, héberger une Frond, appeler une opération.",[170,578,580],{"id":579},"un-autre-hôte","Un autre hôte ?",[148,582,583,584,427],{},"Cette page parle de Nuxt parce que son module fait le montage à votre place. La même Frond\ntourne sous Next, TanStack Start, React Router, SvelteKit et Express — trois d'entre eux\nn'ont besoin d'aucun paquet Fougere. Voir ",[585,586,587],"em",{},[161,588,134],{"href":135},[590,591,592],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":191,"searchDepth":220,"depth":220,"links":594},[595,596,597,598,599],{"id":172,"depth":220,"text":173},{"id":430,"depth":220,"text":431},{"id":523,"depth":220,"text":524},{"id":557,"depth":220,"text":558},{"id":579,"depth":220,"text":580},"Ajouter Fougere progressivement à une app Nuxt existante.","md",{},{"title":20,"description":600},"eEn-McQn4dqrK_UE0sbszeNxS5JbaOqTBaeyZKydjJc",1786637819627]