[{"data":1,"prerenderedAt":2634},["ShallowReactive",2],{"duxt-navigation-docs-docs_fr":3,"i-lucide:puzzle":942,"i-lucide:search":947,"i-simple-icons:meilisearch":949,"docs-fr-FR-\u002Fadd-ons\u002Ftypesense":951,"duxt-preferred-missing-\u002Fadd-ons\u002Ftypesense":945,"i-lucide:rocket":2550,"i-lucide:compass":2552,"i-lucide:book-open":2554,"i-lucide:list":2556,"i-lucide:ruler":2558,"i-lucide:gavel":2560,"i-lucide:copy":2562,"i-lucide:chevron-down":2564,"i-lucide:thumbs-up":2566,"i-lucide:thumbs-down":2568,"i-lucide:star":2570,"i-lucide:circle-alert":2572,"i-simple-icons:discord":2574,"i-lucide:book-open-text":2576,"i-lucide:arrow-up-right":2578,"i-lucide:file-code-2":2580,"duxt-code-ts-export default defineNuxtConfig({\n  extends: ['@kirchdev\u002Fduxt', 'duxt-typesense']\n});\n":13,"i-lucide:info":2582,"i-lucide:lightbulb":2584,"duxt-code-ts-import { defineNuxtModule } from '@nuxt\u002Fkit';\nimport { Client } from 'typesense';\nimport type { DuxtSearchRecord } from '@kirchdev\u002Fduxt\u002Fsearch-records';\nimport { docs } from '..\u002Fserver\u002Ftypesense-schema';\n\nexport default defineNuxtModule({\n  meta: { name: 'typesense-sync' },\n  setup(_options, nuxt) {\n    const key = process.env.TYPESENSE_ADMIN_KEY;\n    \u002F\u002F Pas de clé, c’est un build local, pas un échec : on saute plutôt que\n    \u002F\u002F de le casser.\n    if (!key) return;\n\n    nuxt.hook('duxt:search:records', async (records) => {\n      const client = new Client({\n        nodes: [{ url: process.env.TYPESENSE_URL! }],\n        apiKey: key\n      });\n\n      await sync(client, records);\n    });\n  }\n});\n":13,"duxt-code-ts-async function sync(client: Client, records: readonly DuxtSearchRecord[]) {\n  const collection = client.collections(docs.name);\n\n  \u002F\u002F Typesense ne crée rien implicitement : importer dans une collection\n  \u002F\u002F qui n’existe pas échoue net, c’est donc le premier build qui la crée.\n  if (!(await collection.exists())) await client.collections().create(docs);\n\n  await collection.documents().import(\n    records.map((record) => ({ ...record })),\n    { action: 'upsert' }\n  );\n\n  \u002F\u002F Tout ce que le build n’a pas remis n’est plus sur le site.\n  const kept = new Set(records.map((record) => record.id));\n  const live = await collection.documents().export();\n\n  const stale = live\n    .split('\\n')\n    .filter(Boolean)\n    .map((line) => JSON.parse(line).id as string)\n    .filter((id) => !kept.has(id));\n\n  \u002F\u002F Supprimez par lots : chaque id entre dans la chaîne du filtre, et un\n  \u002F\u002F seul gros renommage en bâtirait un que Typesense refuse.\n  for (let index = 0; index \u003C stale.length; index += 100) {\n    const batch = stale.slice(index, index + 100).join(',');\n    await collection.documents().delete({ filter_by: `id:[${batch}]` });\n  }\n}\n":13,"duxt-code-ts-\u002F\u002F `locale` est la langue du CONTENU, pas la langue de l’interface.\n\u002F\u002F `version` est absente d’une source sans versions : la clause ne s’ajoute\n\u002F\u002F que s’il y en a une ; figée, elle filtrerait sur `undefined`.\nconst filters = [`locale:${locale}`];\nif (version) filters.push(`version:${version}`);\n\nconst results = await client.collections('docs').documents().search({\n  q: query,\n  query_by: 'title,content',\n  filter_by: filters.join(' && ')\n});\n":13,"i-lucide:arrow-left":2586,"i-lucide:arrow-right":2588,"i-lucide:chevron-right":2590,"duxt-version-missing-\u002Fadd-ons\u002Ftypesense":2592,"i-lucide:menu":2601,"i-lucide:keyboard":2603,"i-simple-icons:github":2605,"i-lucide:moon":2607,"package-managers-add @kirchdev\u002Fduxt-typesense":2609,"i-vscode-icons:file-type-light-pnpm":2614,"i-vscode-icons:file-type-pnpm":2617,"i-vscode-icons:file-type-npm":2619,"i-vscode-icons:file-type-yarn":2621,"i-vscode-icons:file-type-bun":2623,"duxt-code-ts-export default defineNuxtConfig({\n  extends: ['@kirchdev\u002Fduxt', '@kirchdev\u002Fduxt-typesense'],\n  duxtTypesense: {\n    endpoint: process.env.TYPESENSE_ENDPOINT,\n    collection: 'docs',\n    adminKey: process.env.TYPESENSE_ADMIN_KEY,\n    searchKey: process.env.TYPESENSE_SEARCH_KEY\n  }\n})\n":13,"package-managers-add -D typesense":2625,"duxt-code-ts-import type { CollectionCreateSchema } from 'typesense';\n\nexport const docs: CollectionCreateSchema = {\n  name: 'docs',\n  fields: [\n    { name: 'url', type: 'string' },\n    { name: 'title', type: 'string' },\n    { name: 'content', type: 'string' },\n    { name: 'source', type: 'string', facet: true },\n    { name: 'version', type: 'string', facet: true, optional: true },\n    { name: 'locale', type: 'string', facet: true }\n  ]\n};\n":13,"i-flag:fr-4x3":2630},[4,31,111,183,826,845,853,878],{"title":5,"path":6,"stem":7,"children":8,"description":12},"Introduction","\u002Fgetting-started","1.getting-started",[9,14,20,26],{"title":5,"path":6,"stem":10,"icon":11,"description":12,"subcategory":13},"1.getting-started\u002Findex","lucide:rocket","Ce qu’est duxt, et ce qui arrive avec une seule ligne de configuration.",null,{"title":15,"path":16,"stem":17,"icon":18,"description":19,"subcategory":13},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F1.installation","lucide:download","Ajoutez la couche, étendez-la, écrivez du Markdown.",{"title":21,"path":22,"stem":23,"icon":24,"description":25,"subcategory":13},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F2.configuration","lucide:settings","Un fichier configure tout le site — ce qu’il contient, et comment il fusionne.",{"title":27,"path":28,"stem":29,"icon":11,"description":30,"subcategory":13},"Démarrer avec le starter","\u002Fgetting-started\u002Ffrom-starter","1.getting-started\u002F3.from-starter","Créez avec Nuxi un site de documentation duxt prêt à démarrer.",{"title":32,"path":33,"stem":34,"children":35,"description":39},"Concepts","\u002Fconcepts","2.concepts",[36,40,46,52,58,64,70,76,81,87,93,99,105],{"title":32,"path":33,"stem":37,"icon":38,"description":39,"subcategory":13},"2.concepts\u002Findex","lucide:compass","Comment fonctionne la couche — le modèle de sources, le schéma d’URL, les collections et les vérifications.",{"title":41,"path":42,"stem":43,"icon":44,"description":45,"subcategory":13},"Couches et surcharge","\u002Fconcepts\u002Flayers","2.concepts\u002F1.layers","lucide:layers","Ce qu’une couche Nuxt vous donne, ce qu’elle vous retire, et quels chemins ne se résolvent pas comme ils se lisent.",{"title":47,"path":48,"stem":49,"icon":50,"description":51,"subcategory":13},"Thématisation","\u002Fconcepts\u002Ftheming","2.concepts\u002F10.theming","lucide:palette","Comment le thème est construit — des composants possédés, une couche de jetons et un mode sombre qui bascule sur une classe.",{"title":53,"path":54,"stem":55,"icon":56,"description":57,"subcategory":13},"Bases de données","\u002Fconcepts\u002Fdatabases","2.concepts\u002F11.databases","lucide:database","Sur quels adaptateurs de base de données de Content un site duxt peut être déployé, lesquels ont été vérifiés, et la seule règle qui garde la couche à l’écart.",{"title":59,"path":60,"stem":61,"icon":62,"description":63,"subcategory":13},"Raccourcis clavier","\u002Fconcepts\u002Fkeyboard-shortcuts","2.concepts\u002F12.keyboard-shortcuts","lucide:keyboard","Les quatre touches que le thème lie, où chacune s'applique, et où la lectrice l'apprend.",{"title":65,"path":66,"stem":67,"icon":68,"description":69,"subcategory":13},"Sources","\u002Fconcepts\u002Fsources","2.concepts\u002F2.sources","lucide:git-branch","Une liste de sources devient chaque collection, préfixe et version que le site sert.",{"title":71,"path":72,"stem":73,"icon":74,"description":75,"subcategory":13},"URL et versions","\u002Fconcepts\u002Furls-and-versions","2.concepts\u002F3.urls-and-versions","lucide:git-compare","Comment apparaissent les segments de dépôt et de version, et ce qu’on dit à un lecteur dans une ancienne version.",{"title":77,"path":78,"stem":79,"icon":56,"description":80,"subcategory":13},"Collections","\u002Fconcepts\u002Fcollections","2.concepts\u002F4.collections","Ce que Content construit à partir des sources, et les quatre choses qu’ajoute le schéma.",{"title":82,"path":83,"stem":84,"icon":85,"description":86,"subcategory":13},"Sections générées","\u002Fconcepts\u002Fgenerated-sections","2.concepts\u002F5.generated-sections","lucide:file-cog","Un artefact plus un type, publiés en pages — ce qu’est le registre, et les deux politiques auxquelles un type répond.",{"title":88,"path":89,"stem":90,"icon":91,"description":92,"subcategory":13},"Ce que la compilation vérifie","\u002Fconcepts\u002Fbuild-checks","2.concepts\u002F6.build-checks","lucide:shield-check","Les échecs silencieux qu’a connus cette couche, transformés en messages.",{"title":94,"path":95,"stem":96,"icon":97,"description":98,"subcategory":13},"Lecteurs machines","\u002Fconcepts\u002Fmachine-readers","2.concepts\u002F7.machine-readers","lucide:bot","Ce qu’obtient un modèle — llms.txt, le Markdown brut de n’importe quelle page et un vrai serveur MCP.",{"title":100,"path":101,"stem":102,"icon":103,"description":104,"subcategory":13},"SEO","\u002Fconcepts\u002Fseo","2.concepts\u002F8.seo","lucide:search","Ce que chaque page émet pour les robots et les cartes sociales, quel module l'écrit, et la seule valeur que la couche ne peut pas deviner.",{"title":106,"path":107,"stem":108,"icon":109,"description":110,"subcategory":13},"Localisation","\u002Fconcepts\u002Flocalisation","2.concepts\u002F9.localisation","lucide:languages","La couche fournit sept locales, et chaque chaîne configurée prend trois formes.",{"title":112,"path":113,"stem":114,"children":115,"description":119},"Guides","\u002Fguides","3.guides",[116,120,126,132,138,143,148,153,159,165,171,177],{"title":112,"path":113,"stem":117,"icon":118,"description":119,"subcategory":13},"3.guides\u002Findex","lucide:book-open","Une tâche par page, du début à la fin — plusieurs dépôts, plusieurs versions, plusieurs langues et un déploiement.",{"title":121,"path":122,"stem":123,"icon":124,"description":125,"subcategory":13},"Plusieurs dépôts","\u002Fguides\u002Fseveral-repositories","3.guides\u002F1.several-repositories","lucide:folder-git","Servir la documentation de plusieurs projets depuis un seul site.",{"title":127,"path":128,"stem":129,"icon":130,"description":131,"subcategory":13},"Publier la documentation d’un provider Terraform","\u002Fguides\u002Fpublish-terraform-provider-docs","3.guides\u002F10.publish-terraform-provider-docs","simple-icons:terraform","Transformer un arbre Markdown tfplugindocs en référence versionnée avec une navigation adaptée au provider.",{"title":133,"path":134,"stem":135,"icon":136,"description":137,"subcategory":13},"Mettre en cache les sources distantes et images OG","\u002Fguides\u002Fcache-build-work","3.guides\u002F11.cache-build-work","lucide:database-zap","Réutiliser les dépôts publics téléchargés et les cartes sociales rendues entre les builds CI.",{"title":139,"path":140,"stem":141,"icon":74,"description":142,"subcategory":13},"Plusieurs versions","\u002Fguides\u002Fseveral-versions","3.guides\u002F2.several-versions","Servir la même documentation sur plusieurs refs, avec un sélecteur et un bandeau.",{"title":144,"path":145,"stem":146,"icon":109,"description":147,"subcategory":13},"Plusieurs langues","\u002Fguides\u002Fseveral-languages","3.guides\u002F3.several-languages","Servir l’interface en plusieurs langues, et traduire les pages elles-mêmes.",{"title":149,"path":150,"stem":151,"icon":50,"description":152,"subcategory":13},"Surcharger le thème","\u002Fguides\u002Foverride-the-theme","3.guides\u002F4.override-the-theme","Changer une couleur, remplacer un composant, ajouter une primitive shadcn-vue.",{"title":154,"path":155,"stem":156,"icon":157,"description":158,"subcategory":13},"Déplacer une page","\u002Fguides\u002Fmove-a-page","3.guides\u002F5.move-a-page","lucide:signpost","redirectFrom dans le frontmatter, transformé en règles de route sous chaque préfixe.",{"title":160,"path":161,"stem":162,"icon":163,"description":164,"subcategory":13},"Déployer un site","\u002Fguides\u002Fdeploy-a-site","3.guides\u002F6.deploy-a-site","lucide:cloud-upload","Où un site duxt peut tourner, ce qu’il lui faut là-bas, et pourquoi le contenu n’est pas rafraîchi à l’exécution.",{"title":166,"path":167,"stem":168,"icon":169,"description":170,"subcategory":13},"Recueillir des retours","\u002Fguides\u002Fcollect-page-feedback","3.guides\u002F7.collect-page-feedback","lucide:thumbs-up","Enveloppez DuxtPageFeedback et gardez la réponse là où vit déjà votre analytique.",{"title":172,"path":173,"stem":174,"icon":175,"description":176,"subcategory":13},"Donner son identité à votre site","\u002Fguides\u002Fbrand-your-site","3.guides\u002F8.brand-your-site","lucide:badge-check","Définir le nom, le logo et les icônes, pour que le site se lise comme le vôtre et non comme celui de la couche.",{"title":178,"path":179,"stem":180,"icon":181,"description":182,"subcategory":13},"Envoyer des événements d’analytique","\u002Fguides\u002Fsend-analytics-events","3.guides\u002F9.send-analytics-events","lucide:chart-line","Une fonction de rappel, cinq événements, aucun fournisseur — branchez les interactions des lecteurs de duxt sur l’analytique que vous utilisez déjà.",{"title":184,"path":185,"stem":186,"children":187,"description":191},"Référence","\u002Freference","4.reference",[188,192,196,228,258,264,268,273,413,570,696,741,801],{"title":184,"path":185,"stem":189,"icon":190,"description":191,"subcategory":13},"4.reference\u002Findex","lucide:list","La surface publique de la couche — clés de configuration, frontmatter, composants, composables et points de terminaison.",{"title":21,"path":193,"stem":194,"icon":24,"description":195,"subcategory":13},"\u002Freference\u002Fconfiguration","4.reference\u002F1.configuration","Chaque clé sous duxt dans app.config.ts — ce qu’elle contrôle, et quand elle est lue.",{"title":197,"path":198,"stem":199,"children":200,"icon":202,"description":203,"subcategory":13},"Journal des versions","\u002Freference\u002Fchangelog","4.reference\u002F10.changelog\u002Findex",[201,204,210,216,222],{"title":197,"path":198,"stem":199,"icon":202,"description":203,"subcategory":13},"lucide:tag","Un journal de releases, publié en pages — une chronologie, une page par version, et un flux.",{"title":205,"path":206,"stem":207,"icon":208,"description":209,"subcategory":13},"Déclarer la section","\u002Freference\u002Fchangelog\u002Fsection","4.reference\u002F10.changelog\u002F1.section","lucide:file-clock","Le type de section `changelog` — où vit le fichier, et les deux politiques auxquelles il répond.",{"title":211,"path":212,"stem":213,"icon":214,"description":215,"subcategory":13},"Granularité","\u002Freference\u002Fchangelog\u002Fgranularity","4.reference\u002F10.changelog\u002F2.granularity","lucide:split","Une page par version, ou le fichier comme l’unique page qu’il a été écrit.",{"title":217,"path":218,"stem":219,"icon":220,"description":221,"subcategory":13},"Ce qui est lu","\u002Freference\u002Fchangelog\u002Fwhat-is-read","4.reference\u002F10.changelog\u002F3.what-is-read","lucide:scan-text","Quels titres deviennent des versions, lesquels des groupes, et ce qu’il advient du reste.",{"title":223,"path":224,"stem":225,"icon":226,"description":227,"subcategory":13},"Mise en page et composants","\u002Freference\u002Fchangelog\u002Fcomponents","4.reference\u002F10.changelog\u002F4.components","lucide:box","La mise en page dans laquelle se rend un historique éclaté, et les deux composants MDC dont ses pages sont faites.",{"title":229,"path":230,"stem":231,"children":232,"icon":234,"description":235,"subcategory":13},"Collections Bruno","\u002Freference\u002Fbruno","4.reference\u002F11.bruno\u002Findex",[233,236,241,247,253],{"title":229,"path":230,"stem":231,"icon":234,"description":235,"subcategory":13},"lucide:send","Une collection Bruno publiée en référence centrée sur les requêtes, avec une archive téléchargeable.",{"title":205,"path":237,"stem":238,"icon":239,"description":240,"subcategory":13},"\u002Freference\u002Fbruno\u002Fsection","4.reference\u002F11.bruno\u002F1.section","lucide:file-code","Où vit une collection Bruno, quelles pages elle produit et quelles options elle accepte.",{"title":242,"path":243,"stem":244,"icon":245,"description":246,"subcategory":13},"Ce qui est publié","\u002Freference\u002Fbruno\u002Fwhat-is-published","4.reference\u002F11.bruno\u002F2.what-is-published","lucide:shield","Environnements, identifiants, scripts et tests n’atteignent jamais une page.",{"title":248,"path":249,"stem":250,"icon":251,"description":252,"subcategory":13},"Le client de requêtes","\u002Freference\u002Fbruno\u002Ftry-it","4.reference\u002F11.bruno\u002F3.try-it","lucide:send-horizontal","Désactivé par défaut et dirigé uniquement vers une cible déclarée publique.",{"title":254,"path":255,"stem":256,"icon":18,"description":257,"subcategory":13},"Obtenir la collection","\u002Freference\u002Fbruno\u002Fgetting-the-collection","4.reference\u002F11.bruno\u002F4.getting-the-collection","L’archive est liée à la version et à la langue affichées ; le lien Bruno ne l’est pas.",{"title":259,"path":260,"stem":261,"icon":262,"description":263,"subcategory":13},"Hooks","\u002Freference\u002Fhooks","4.reference\u002F12.hooks","lucide:plug","L’unique hook de build que duxt émet, ce qu’il vous remet et pourquoi il n’y en a qu’un.",{"title":65,"path":265,"stem":266,"icon":68,"description":267,"subcategory":13},"\u002Freference\u002Fsources","4.reference\u002F2.sources","Les champs d’une entrée de source, ses refs, et les options qui façonnent les URL.",{"title":269,"path":270,"stem":271,"icon":239,"description":272,"subcategory":13},"Frontmatter","\u002Freference\u002Ffrontmatter","4.reference\u002F3.frontmatter","Les champs qu’une page peut porter au-delà du titre et de la description, et les deux que la compilation remplit.",{"title":274,"path":275,"stem":276,"children":277,"icon":279,"description":280,"subcategory":13},"Composants MDC","\u002Freference\u002Fmdc-components","4.reference\u002F4.mdc-components\u002Findex",[278,281,287,293,299,305,311,317,323,329,367,373,378,384,390,396,402,408],{"title":274,"path":275,"stem":276,"icon":279,"description":280,"subcategory":13},"lucide:blocks","Les blocs qu’une page Markdown peut appeler, une page chacun, avec leurs props.",{"title":282,"path":283,"stem":284,"icon":285,"description":286,"subcategory":13},"Callout","\u002Freference\u002Fmdc-components\u002Fcallout","4.reference\u002F4.mdc-components\u002F1.callout","lucide:message-square-warning","Un encadré où le lecteur est censé s’arrêter — une astuce, un avertissement, un danger.",{"title":288,"path":289,"stem":290,"icon":291,"description":292,"subcategory":13},"Gestionnaires de paquets","\u002Freference\u002Fmdc-components\u002Fpackage-managers","4.reference\u002F4.mdc-components\u002F10.package-managers","lucide:package","Une commande, un onglet par gestionnaire de paquets, mémorisé d’une page à l’autre.",{"title":294,"path":295,"stem":296,"icon":297,"description":298,"subcategory":13},"Arborescence de fichiers","\u002Freference\u002Fmdc-components\u002Ffile-tree","4.reference\u002F4.mdc-components\u002F11.file-tree","lucide:folder-tree","Une structure de dossiers, avec une icône par type de fichier.",{"title":300,"path":301,"stem":302,"icon":303,"description":304,"subcategory":13},"Aperçu","\u002Freference\u002Fmdc-components\u002Fpreview","4.reference\u002F4.mdc-components\u002F12.preview","lucide:eye","Un composant rendu tel que la page le rend, avec sa source à côté.",{"title":306,"path":307,"stem":308,"icon":309,"description":310,"subcategory":13},"Cartes de page","\u002Freference\u002Fmdc-components\u002Fpage-cards","4.reference\u002F4.mdc-components\u002F13.page-cards","lucide:layout-grid","Les enfants d’une section, en cartes.",{"title":312,"path":313,"stem":314,"icon":315,"description":316,"subcategory":13},"Partial","\u002Freference\u002Fmdc-components\u002Fpartial","4.reference\u002F4.mdc-components\u002F14.partial","lucide:puzzle","Un bloc écrit une fois et rendu dans chaque source qui en a besoin.",{"title":318,"path":319,"stem":320,"icon":321,"description":322,"subcategory":13},"Since","\u002Freference\u002Fmdc-components\u002Fsince","4.reference\u002F4.mdc-components\u002F15.since","lucide:milestone","La version dans laquelle une chose est arrivée, à côté d’un titre.",{"title":324,"path":325,"stem":326,"icon":327,"description":328,"subcategory":13},"Mermaid","\u002Freference\u002Fmdc-components\u002Fmermaid","4.reference\u002F4.mdc-components\u002F16.mermaid","lucide:workflow","Un diagramme depuis un bloc ou une prop.",{"title":330,"path":331,"stem":332,"children":333,"icon":335,"description":336,"subcategory":13},"Surcharges de prose","\u002Freference\u002Fmdc-components\u002Fprose","4.reference\u002F4.mdc-components\u002F17.prose\u002Findex",[334,337,343,349,355,361],{"title":330,"path":331,"stem":332,"icon":335,"description":336,"subcategory":13},"lucide:type","Ce que la couche change au Markdown ordinaire — liens, titres, images, code et tableaux.",{"title":338,"path":339,"stem":340,"icon":341,"description":342,"subcategory":13},"ProseA","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-a","4.reference\u002F4.mdc-components\u002F17.prose\u002F1.prose-a","lucide:link","Un lien, résolu selon la source dans laquelle il a été écrit.",{"title":344,"path":345,"stem":346,"icon":347,"description":348,"subcategory":13},"ProseH2, ProseH3, ProseH4","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-headings","4.reference\u002F4.mdc-components\u002F17.prose\u002F2.prose-headings","lucide:heading","Des titres, chacun avec une ancre de permalien.",{"title":350,"path":351,"stem":352,"icon":353,"description":354,"subcategory":13},"ProseImg","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-img","4.reference\u002F4.mdc-components\u002F17.prose\u002F3.prose-img","lucide:image","Une image : consciente du thème, adaptative et agrandissable.",{"title":356,"path":357,"stem":358,"icon":359,"description":360,"subcategory":13},"ProsePre","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-pre","4.reference\u002F4.mdc-components\u002F17.prose\u002F4.prose-pre","lucide:terminal","Le bloc de code : nom de fichier, icône de langage, bouton de copie.",{"title":362,"path":363,"stem":364,"icon":365,"description":366,"subcategory":13},"ProseTable","\u002Freference\u002Fmdc-components\u002Fprose\u002Fprose-table","4.reference\u002F4.mdc-components\u002F17.prose\u002F5.prose-table","lucide:table","Un tableau qui défile à la place de la page.",{"title":368,"path":369,"stem":370,"icon":371,"description":372,"subcategory":13},"Étapes","\u002Freference\u002Fmdc-components\u002Fsteps","4.reference\u002F4.mdc-components\u002F2.steps","lucide:list-ordered","Une liste ordonnée dessinée en étapes numérotées sur un rail.",{"title":374,"path":375,"stem":376,"icon":239,"description":377,"subcategory":13},"Groupe de code","\u002Freference\u002Fmdc-components\u002Fcode-group","4.reference\u002F4.mdc-components\u002F3.code-group","Plusieurs blocs de code en un seul bloc à onglets, étiquetés par nom de fichier.",{"title":379,"path":380,"stem":381,"icon":382,"description":383,"subcategory":13},"Groupe d'onglets","\u002Freference\u002Fmdc-components\u002Ftab-group","4.reference\u002F4.mdc-components\u002F4.tab-group","lucide:panels-top-left","Des onglets pour tout ce qui n’est pas du code.",{"title":385,"path":386,"stem":387,"icon":388,"description":389,"subcategory":13},"Tab","\u002Freference\u002Fmdc-components\u002Ftab","4.reference\u002F4.mdc-components\u002F5.tab","lucide:square","Un panneau d’un groupe d’onglets.",{"title":391,"path":392,"stem":393,"icon":394,"description":395,"subcategory":13},"Accordion","\u002Freference\u002Fmdc-components\u002Faccordion","4.reference\u002F4.mdc-components\u002F6.accordion","lucide:chevrons-up-down","Des sections repliables — une FAQ, ou des réponses parmi lesquelles le lecteur choisit.",{"title":397,"path":398,"stem":399,"icon":400,"description":401,"subcategory":13},"Élément d'accordéon","\u002Freference\u002Fmdc-components\u002Faccordion-item","4.reference\u002F4.mdc-components\u002F7.accordion-item","lucide:chevron-down","Une section repliable.",{"title":403,"path":404,"stem":405,"icon":406,"description":407,"subcategory":13},"Groupe de champs","\u002Freference\u002Fmdc-components\u002Ffield-group","4.reference\u002F4.mdc-components\u002F8.field-group","lucide:list-tree","Une liste de champs, en un seul bloc.",{"title":409,"path":410,"stem":411,"icon":202,"description":412,"subcategory":13},"Champ","\u002Freference\u002Fmdc-components\u002Ffield","4.reference\u002F4.mdc-components\u002F9.field","Un paramètre, une propriété ou une option, avec son type et sa valeur par défaut.",{"title":414,"path":415,"stem":416,"children":417,"icon":419,"description":420,"subcategory":13},"Composants","\u002Freference\u002Fcomponents","4.reference\u002F5.components\u002Findex",[418,421,447,488,539],{"title":414,"path":415,"stem":416,"icon":419,"description":420,"subcategory":13},"lucide:component","Les composants propres à la couche, une page chacun — à quoi sert chacun, et ce qu’il prend.",{"title":422,"path":423,"stem":424,"children":425,"icon":427,"description":428,"subcategory":13},"Mise en page","\u002Freference\u002Fcomponents\u002Flayout","4.reference\u002F5.components\u002F1.layout\u002Findex",[426,429,435,441],{"title":422,"path":423,"stem":424,"icon":427,"description":428,"subcategory":13},"lucide:layout-panel-top","Les deux composants qui encadrent une page — la barre de navigation et le pied de page.",{"title":430,"path":431,"stem":432,"icon":433,"description":434,"subcategory":13},"DuxtHeader","\u002Freference\u002Fcomponents\u002Flayout\u002Fduxt-header","4.reference\u002F5.components\u002F1.layout\u002F1.duxt-header","lucide:panel-top","La barre de navigation : titre, navigation, recherche et liens en icônes.",{"title":436,"path":437,"stem":438,"icon":439,"description":440,"subcategory":13},"DuxtFooter","\u002Freference\u002Fcomponents\u002Flayout\u002Fduxt-footer","4.reference\u002F5.components\u002F1.layout\u002F2.duxt-footer","lucide:panel-bottom","Le pied de page : le nom du site, ses liens légaux, et la ligne propre à la couche.",{"title":442,"path":443,"stem":444,"icon":445,"description":446,"subcategory":13},"DuxtAnnouncements","\u002Freference\u002Fcomponents\u002Flayout\u002Fduxt-announcements","4.reference\u002F5.components\u002F1.layout\u002F3.duxt-announcements","lucide:megaphone","Les avis du site, dessinés par emplacement uniquement lorsqu’il y a quelque chose à annoncer.",{"title":448,"path":449,"stem":450,"children":451,"icon":38,"description":453,"subcategory":13},"Navigation","\u002Freference\u002Fcomponents\u002Fnavigation","4.reference\u002F5.components\u002F2.navigation\u002Findex",[452,454,460,465,471,477,482],{"title":448,"path":449,"stem":450,"icon":38,"description":453,"subcategory":13},"Se déplacer — la rangée des sections, la barre latérale, le fil d’Ariane, le sommaire et précédent\u002Fsuivant.",{"title":455,"path":456,"stem":457,"icon":458,"description":459,"subcategory":13},"DuxtSections","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-sections","4.reference\u002F5.components\u002F2.navigation\u002F1.duxt-sections","lucide:rows-3","La deuxième rangée de la barre de navigation — les parties de premier niveau de la documentation.",{"title":461,"path":462,"stem":463,"icon":406,"description":464,"subcategory":13},"DuxtNavigation","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-navigation","4.reference\u002F5.components\u002F2.navigation\u002F2.duxt-navigation","L’arbre de la barre latérale.",{"title":466,"path":467,"stem":468,"icon":469,"description":470,"subcategory":13},"DuxtNavigationLink","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-navigation-link","4.reference\u002F5.components\u002F2.navigation\u002F3.duxt-navigation-link","lucide:link-2","Une entrée de la barre latérale.",{"title":472,"path":473,"stem":474,"icon":475,"description":476,"subcategory":13},"DuxtBreadcrumb","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-breadcrumb","4.reference\u002F5.components\u002F2.navigation\u002F4.duxt-breadcrumb","lucide:chevrons-right","Le fil au-dessus du titre de page.",{"title":478,"path":479,"stem":480,"icon":190,"description":481,"subcategory":13},"DuxtToc","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-toc","4.reference\u002F5.components\u002F2.navigation\u002F5.duxt-toc","Le sommaire, et l’encart en dessous.",{"title":483,"path":484,"stem":485,"icon":486,"description":487,"subcategory":13},"DuxtPageNav","\u002Freference\u002Fcomponents\u002Fnavigation\u002Fduxt-page-nav","4.reference\u002F5.components\u002F2.navigation\u002F6.duxt-page-nav","lucide:arrow-left-right","Précédent et suivant, bornés par la section.",{"title":489,"path":490,"stem":491,"children":492,"icon":494,"description":495,"subcategory":13},"Contrôles","\u002Freference\u002Fcomponents\u002Fcontrols","4.reference\u002F5.components\u002F3.controls\u002Findex",[493,496,501,506,512,517,523,528,534],{"title":489,"path":490,"stem":491,"icon":494,"description":495,"subcategory":13},"lucide:sliders-horizontal","Ce qu’actionne un lecteur — la recherche, les sélecteurs, la fiche des raccourcis et deux indicateurs.",{"title":497,"path":498,"stem":499,"icon":103,"description":500,"subcategory":13},"DuxtSearch","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-search","4.reference\u002F5.components\u002F3.controls\u002F1.duxt-search","Rechercher chaque source active et entrelacer ses résultats classés localement.",{"title":502,"path":503,"stem":504,"icon":44,"description":505,"subcategory":13},"DuxtVersion","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-version","4.reference\u002F5.components\u002F3.controls\u002F2.duxt-version","Le badge de version, et le sélecteur quand il y en a plusieurs.",{"title":507,"path":508,"stem":509,"icon":510,"description":511,"subcategory":13},"DuxtVersionBanner","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-version-banner","4.reference\u002F5.components\u002F3.controls\u002F3.duxt-version-banner","lucide:triangle-alert","Le bandeau qui dit au lecteur que cette version n’est pas la version courante.",{"title":513,"path":514,"stem":515,"icon":109,"description":516,"subcategory":13},"DuxtLocale","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-locale","4.reference\u002F5.components\u002F3.controls\u002F4.duxt-locale","Le sélecteur de langue.",{"title":518,"path":519,"stem":520,"icon":521,"description":522,"subcategory":13},"DuxtProgress","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-progress","4.reference\u002F5.components\u002F3.controls\u002F5.duxt-progress","lucide:loader","Jusqu’où le lecteur est descendu dans la page.",{"title":524,"path":525,"stem":526,"icon":62,"description":527,"subcategory":13},"DuxtShortcuts","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-shortcuts","4.reference\u002F5.components\u002F3.controls\u002F6.duxt-shortcuts","La fiche des raccourcis clavier, sur ?.",{"title":529,"path":530,"stem":531,"icon":532,"description":533,"subcategory":13},"DuxtSkipLink","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-skip-link","4.reference\u002F5.components\u002F3.controls\u002F7.duxt-skip-link","lucide:skip-forward","Le premier élément focalisable de la page.",{"title":535,"path":536,"stem":537,"icon":62,"description":538,"subcategory":13},"DuxtShortcutsTrigger","\u002Freference\u002Fcomponents\u002Fcontrols\u002Fduxt-shortcuts-trigger","4.reference\u002F5.components\u002F3.controls\u002F8.duxt-shortcuts-trigger","Le bouton qui ouvre la liste des raccourcis.",{"title":540,"path":541,"stem":542,"children":543,"icon":545,"description":546,"subcategory":13},"Page","\u002Freference\u002Fcomponents\u002Fpage","4.reference\u002F5.components\u002F4.page\u002Findex",[544,547,553,559,564],{"title":540,"path":541,"stem":542,"icon":545,"description":546,"subcategory":13},"lucide:file-text","Les composants qui appartiennent à la page elle-même.",{"title":548,"path":549,"stem":550,"icon":551,"description":552,"subcategory":13},"DuxtPageInfo","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-page-info","4.reference\u002F5.components\u002F4.page\u002F1.duxt-page-info","lucide:git-commit-horizontal","D’où vient la page : lien d’édition, dernière mise à jour, contributeurs.",{"title":554,"path":555,"stem":556,"icon":557,"description":558,"subcategory":13},"DuxtCopyPage","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-copy-page","4.reference\u002F5.components\u002F4.page\u002F2.duxt-copy-page","lucide:clipboard-copy","Donnez cette page à un modèle, ou lisez sa source.",{"title":560,"path":561,"stem":562,"icon":169,"description":563,"subcategory":13},"DuxtPageFeedback","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-page-feedback","4.reference\u002F5.components\u002F4.page\u002F3.duxt-page-feedback","« Cette page vous a-t-elle été utile ? » — un événement, et pas de backend.",{"title":565,"path":566,"stem":567,"icon":568,"description":569,"subcategory":13},"DuxtCodeBlock","\u002Freference\u002Fcomponents\u002Fpage\u002Fduxt-code-block","4.reference\u002F5.components\u002F4.page\u002F4.duxt-code-block","lucide:code","La carte autour d’un bloc de code.",{"title":571,"path":572,"stem":573,"children":574,"icon":576,"description":577,"subcategory":13},"Composables","\u002Freference\u002Fcomposables","4.reference\u002F6.composables\u002Findex",[575,578,612,641],{"title":571,"path":572,"stem":573,"icon":576,"description":577,"subcategory":13},"lucide:function-square","Les fonctions que la couche expose à vos propres composants, une page chacune.",{"title":579,"path":580,"stem":581,"children":582,"icon":56,"description":584,"subcategory":13},"Configuration et contenu","\u002Freference\u002Fcomposables\u002Fconfig-and-content","4.reference\u002F6.composables\u002F1.config-and-content\u002Findex",[583,585,590,596,601,607],{"title":579,"path":580,"stem":581,"icon":56,"description":584,"subcategory":13},"La configuration fusionnée, et quelle collection sert la page en cours de lecture.",{"title":586,"path":587,"stem":588,"icon":24,"description":589,"subcategory":13},"useDuxtConfig()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-config","4.reference\u002F6.composables\u002F1.config-and-content\u002F1.use-duxt-config","La configuration fusionnée, chaque champ de texte déjà résolu.",{"title":591,"path":592,"stem":593,"icon":594,"description":595,"subcategory":13},"useDuxtCollection()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-collection","4.reference\u002F6.composables\u002F1.config-and-content\u002F2.use-duxt-collection","lucide:library","Quelle collection sert cette route.",{"title":597,"path":598,"stem":599,"icon":406,"description":600,"subcategory":13},"useDuxtNavigation()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-navigation","4.reference\u002F6.composables\u002F1.config-and-content\u002F3.use-duxt-navigation","L’arbre de navigation de la collection qui sert cette route.",{"title":602,"path":603,"stem":604,"icon":605,"description":606,"subcategory":13},"useDuxtSection()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-section","4.reference\u002F6.composables\u002F1.config-and-content\u002F4.use-duxt-section","lucide:folder-open","La partie de la documentation dans laquelle se trouve cette page.",{"title":608,"path":609,"stem":610,"icon":475,"description":611,"subcategory":13},"useDuxtBreadcrumb()","\u002Freference\u002Fcomposables\u002Fconfig-and-content\u002Fuse-duxt-breadcrumb","4.reference\u002F6.composables\u002F1.config-and-content\u002F5.use-duxt-breadcrumb","Le fil qui descend de la section jusqu’à une page.",{"title":613,"path":614,"stem":615,"children":616,"icon":618,"description":619,"subcategory":13},"Chemins et versions","\u002Freference\u002Fcomposables\u002Fpaths-and-versions","4.reference\u002F6.composables\u002F2.paths-and-versions\u002Findex",[617,620,625,630,635],{"title":613,"path":614,"stem":615,"icon":618,"description":619,"subcategory":13},"lucide:route","Lire une URL, en écrire une en retour, et savoir quelle version est lue.",{"title":621,"path":622,"stem":623,"icon":321,"description":624,"subcategory":13},"useDuxtPath()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-path","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F1.use-duxt-path","Le chemin où se trouve la documentation, locale retirée.",{"title":626,"path":627,"stem":628,"icon":341,"description":629,"subcategory":13},"useDuxtLink()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-link","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F2.use-duxt-link","Un chemin de documentation, réécrit en lien.",{"title":631,"path":632,"stem":633,"icon":44,"description":634,"subcategory":13},"useDuxtVersion()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-version","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F3.use-duxt-version","Ce que montre le sélecteur, ce que dit la bannière, s’il faut indexer.",{"title":636,"path":637,"stem":638,"icon":639,"description":640,"subcategory":13},"useDuxtSiteUrl()","\u002Freference\u002Fcomposables\u002Fpaths-and-versions\u002Fuse-duxt-site-url","4.reference\u002F6.composables\u002F2.paths-and-versions\u002F4.use-duxt-site-url","lucide:globe","L’origine configurée, et les chemins rendus absolus.",{"title":642,"path":643,"stem":644,"children":645,"icon":118,"description":647,"subcategory":13},"Expérience de lecture","\u002Freference\u002Fcomposables\u002Freading","4.reference\u002F6.composables\u002F3.reading\u002Findex",[646,648,652,658,663,669,675,680,686,691],{"title":642,"path":643,"stem":644,"icon":118,"description":647,"subcategory":13},"La recherche, les titres, le focus, l’historique, et les choix que fait un lecteur.",{"title":649,"path":650,"stem":651,"icon":103,"description":500,"subcategory":13},"useDuxtSearch()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-search","4.reference\u002F6.composables\u002F3.reading\u002F1.use-duxt-search",{"title":653,"path":654,"stem":655,"icon":656,"description":657,"subcategory":13},"useFuzzySearch()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-fuzzy-search","4.reference\u002F6.composables\u002F3.reading\u002F2.use-fuzzy-search","lucide:spell-check","La tolérance aux fautes de frappe, à côté de l’index exact.",{"title":659,"path":660,"stem":661,"icon":347,"description":662,"subcategory":13},"useActiveHeading()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-active-heading","4.reference\u002F6.composables\u002F3.reading\u002F3.use-active-heading","Le titre actuellement en vue.",{"title":664,"path":665,"stem":666,"icon":667,"description":668,"subcategory":13},"useDuxtPageFocus()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-page-focus","4.reference\u002F6.composables\u002F3.reading\u002F4.use-duxt-page-focus","lucide:focus","Déplace le focus vers le titre après une navigation côté client.",{"title":670,"path":671,"stem":672,"icon":673,"description":674,"subcategory":13},"useRecentPages()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-recent-pages","4.reference\u002F6.composables\u002F3.reading\u002F5.use-recent-pages","lucide:history","Les pages ouvertes le plus récemment, jusqu’à la limite configurée.",{"title":676,"path":677,"stem":678,"icon":291,"description":679,"subcategory":13},"usePackageManager()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-package-manager","4.reference\u002F6.composables\u002F3.reading\u002F6.use-package-manager","Le gestionnaire de paquets qu’un lecteur a choisi.",{"title":681,"path":682,"stem":683,"icon":684,"description":685,"subcategory":13},"useDuxtToast()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-toast","4.reference\u002F6.composables\u002F3.reading\u002F7.use-duxt-toast","lucide:bell","Les notifications, enveloppées pour qu’aucun composant n’importe la bibliothèque.",{"title":687,"path":688,"stem":689,"icon":62,"description":690,"subcategory":13},"useDuxtShortcuts()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-shortcuts","4.reference\u002F6.composables\u002F3.reading\u002F8.use-duxt-shortcuts","Les touches que le thème écoute.",{"title":692,"path":693,"stem":694,"icon":181,"description":695,"subcategory":13},"useDuxtAnalytics()","\u002Freference\u002Fcomposables\u002Freading\u002Fuse-duxt-analytics","4.reference\u002F6.composables\u002F3.reading\u002F9.use-duxt-analytics","Rapporter une interaction de lecteur à la fonction de rappel propre au site, ou à personne.",{"title":697,"path":698,"stem":699,"children":700,"icon":618,"description":702,"subcategory":13},"Points de terminaison","\u002Freference\u002Fendpoints","4.reference\u002F7.endpoints\u002Findex",[701,703,708,714,719,724,729,735],{"title":697,"path":698,"stem":699,"icon":618,"description":702,"subcategory":13},"Tout ce que le site sert en dehors des pages, une page pour chacun.",{"title":704,"path":705,"stem":706,"icon":545,"description":707,"subcategory":13},"\u002Fllms.txt","\u002Freference\u002Fendpoints\u002Fllms-txt","4.reference\u002F7.endpoints\u002F1.llms-txt","La documentation en index Markdown, selon llmstxt.org.",{"title":709,"path":710,"stem":711,"icon":712,"description":713,"subcategory":13},"\u002Fllms-full.txt","\u002Freference\u002Fendpoints\u002Fllms-full-txt","4.reference\u002F7.endpoints\u002F2.llms-full-txt","lucide:file-stack","Une extension duxt avec les mêmes pages dans un fichier Markdown.",{"title":715,"path":716,"stem":717,"icon":239,"description":718,"subcategory":13},"\u003Cpage>.md","\u002Freference\u002Fendpoints\u002Fpage-markdown","4.reference\u002F7.endpoints\u002F3.page-markdown","La source de n’importe quelle page, à son URL suivie de .md.",{"title":720,"path":721,"stem":722,"icon":97,"description":723,"subcategory":13},"\u002Fmcp","\u002Freference\u002Fendpoints\u002Fmcp","4.reference\u002F7.endpoints\u002F4.mcp","Un serveur MCP sur le même contenu.",{"title":725,"path":726,"stem":727,"icon":103,"description":728,"subcategory":13},"\u002Fsitemap.xml et \u002Frobots.txt","\u002Freference\u002Fendpoints\u002Fsitemap-and-robots","4.reference\u002F7.endpoints\u002F5.sitemap-and-robots","Ce vers quoi un robot est dirigé, et ce dont on le tient à l’écart.",{"title":730,"path":731,"stem":732,"icon":733,"description":734,"subcategory":13},"\u002Frss.xml","\u002Freference\u002Fendpoints\u002Frss-xml","4.reference\u002F7.endpoints\u002F6.rss-xml","lucide:rss","Le flux, une fois qu’une section est nommée.",{"title":736,"path":737,"stem":738,"icon":739,"description":740,"subcategory":13},"\u002F_duxt\u002Fdevtools","\u002Freference\u002Fendpoints\u002Fdevtools","4.reference\u002F7.endpoints\u002F7.devtools","lucide:wrench","La route depuis laquelle le panneau Nuxt Devtools est servi. En développement seulement.",{"title":742,"path":743,"stem":744,"children":745,"icon":739,"description":747,"subcategory":13},"Devtools","\u002Freference\u002Fdevtools","4.reference\u002F8.devtools\u002Findex",[746,748,752,757,762,768,774,780,785,790,795],{"title":742,"path":743,"stem":744,"icon":739,"description":747,"subcategory":13},"Dix panneaux qui montrent ce que vos sources sont devenues. En développement seulement.",{"title":65,"path":749,"stem":750,"icon":594,"description":751,"subcategory":13},"\u002Freference\u002Fdevtools\u002Fsources","4.reference\u002F8.devtools\u002F1.sources","Ce que `duxt.sources` est devenu — une collection par source, version et langue.",{"title":753,"path":754,"stem":755,"icon":157,"description":756,"subcategory":13},"Redirections","\u002Freference\u002Fdevtools\u002Fredirects","4.reference\u002F8.devtools\u002F10.redirects","Chaque redirection que sert le serveur, et lesquelles la couche a écrites.",{"title":758,"path":759,"stem":760,"icon":618,"description":761,"subcategory":13},"Chemins","\u002Freference\u002Fdevtools\u002Fpaths","4.reference\u002F8.devtools\u002F2.paths","Collez une URL et voyez quelle source la revendique et ce qu’elle y trouve.",{"title":763,"path":764,"stem":765,"icon":766,"description":767,"subcategory":13},"Pages","\u002Freference\u002Fdevtools\u002Fpages","4.reference\u002F8.devtools\u002F3.pages","lucide:files","Chaque page de chaque collection, avec son frontmatter et ses métadonnées git.",{"title":769,"path":770,"stem":771,"icon":772,"description":773,"subcategory":13},"Versions","\u002Freference\u002Fdevtools\u002Fversions","4.reference\u002F8.devtools\u002F4.versions","lucide:columns-3","Quelle version — et quelle langue — porte quelle page.",{"title":775,"path":776,"stem":777,"icon":778,"description":779,"subcategory":13},"Vérifications","\u002Freference\u002Fdevtools\u002Fchecks","4.reference\u002F8.devtools\u002F5.checks","lucide:check-check","Le validateur du build, appliqué à ce que le site sert en ce moment.",{"title":781,"path":782,"stem":783,"icon":103,"description":784,"subcategory":13},"Recherche","\u002Freference\u002Fdevtools\u002Fsearch","4.reference\u002F8.devtools\u002F6.search","Ce que contient l’index de recherche, via la requête même que lance la boîte de dialogue.",{"title":786,"path":787,"stem":788,"icon":494,"description":789,"subcategory":13},"Config","\u002Freference\u002Fdevtools\u002Fconfig","4.reference\u002F8.devtools\u002F7.config","La configuration `duxt` fusionnée, et de quel côté de la fusion vient chaque valeur.",{"title":791,"path":792,"stem":793,"icon":109,"description":794,"subcategory":13},"i18n","\u002Freference\u002Fdevtools\u002Fi18n","4.reference\u002F8.devtools\u002F8.i18n","Clés de message par langue, face à la langue de base.",{"title":796,"path":797,"stem":798,"icon":799,"description":800,"subcategory":13},"Cache","\u002Freference\u002Fdevtools\u002Fcache","4.reference\u002F8.devtools\u002F9.cache","lucide:hard-drive","Le cache de téléchargement de Content, et un moyen d’en jeter une entrée.",{"title":802,"path":803,"stem":804,"children":805,"icon":262,"description":807,"subcategory":13},"Référence de l’API","\u002Freference\u002Fopenapi","4.reference\u002F9.openapi\u002Findex",[806,808,812,816,821],{"title":802,"path":803,"stem":804,"icon":262,"description":807,"subcategory":13},"Un document OpenAPI, publié en pages de référence avec un client qui envoie de vraies requêtes.",{"title":205,"path":809,"stem":810,"icon":239,"description":811,"subcategory":13},"\u002Freference\u002Fopenapi\u002Fsection","4.reference\u002F9.openapi\u002F1.section","Le type de section `openapi` — où vit le document, et ce qu’il devient.",{"title":414,"path":813,"stem":814,"icon":226,"description":815,"subcategory":13},"\u002Freference\u002Fopenapi\u002Fcomponents","4.reference\u002F9.openapi\u002F2.components","Les trois composants MDC dont est faite une page de référence générée.",{"title":817,"path":818,"stem":819,"icon":234,"description":820,"subcategory":13},"Le client d’essai","\u002Freference\u002Fopenapi\u002Ftry-it","4.reference\u002F9.openapi\u002F3.try-it","Une vraie requête, envoyée par le navigateur du lecteur lui-même.",{"title":822,"path":823,"stem":824,"icon":568,"description":825,"subcategory":13},"Échantillons de requête","\u002Freference\u002Fopenapi\u002Frequest-samples","4.reference\u002F9.openapi\u002F4.request-samples","La même requête dans douze clients, et comment ajouter le vôtre.",{"title":827,"path":828,"stem":829,"children":830,"description":833},"Extensions","\u002Fadd-ons","5.add-ons",[831,834,839],{"title":827,"path":828,"stem":832,"icon":315,"description":833,"subcategory":13},"5.add-ons\u002Findex","Des layers compagnons qui étendent un site duxt — chacun est un paquet à part, ajouté par une entrée de plus dans extends.",{"title":835,"path":836,"stem":837,"icon":103,"description":838,"subcategory":13},"Typesense","\u002Fadd-ons\u002Ftypesense","5.add-ons\u002F1.typesense","Consommez l’unique hook de build de duxt dans une collection Typesense — chaque source, version et langue, mise à jour par un id stable.",{"title":840,"path":841,"stem":842,"icon":843,"description":844,"subcategory":13},"Meilisearch","\u002Fadd-ons\u002Fmeilisearch","5.add-ons\u002F2.meilisearch","simple-icons:meilisearch","Ajouter la couche complémentaire officielle pour une indexation atomique à la compilation et une recherche facultative dans le navigateur.",{"title":846,"path":847,"stem":848,"children":849,"icon":851,"description":852,"subcategory":13},"Crédits","\u002Fcredits","6.credits\u002Findex",[850],{"title":846,"path":847,"stem":848,"icon":851,"description":852,"subcategory":13},"lucide:heart","Ce sur quoi duxt est construit, et ce d’après quoi il l’a été.",{"title":854,"path":855,"stem":856,"children":857,"description":861},"Conventions","\u002Fconventions","7.conventions",[858,862,868,873],{"title":854,"path":855,"stem":859,"icon":860,"description":861,"subcategory":13},"7.conventions\u002Findex","lucide:ruler","Règles propres au projet — celles qu'on ne peut pas déduire du code.",{"title":863,"path":864,"stem":865,"icon":866,"description":867,"subcategory":13},"Identité visuelle","\u002Fconventions\u002Fbranding","7.conventions\u002F1.branding","lucide:shapes","La marque [d]uxt — où sert chaque ressource, pourquoi les crochets de l'icône sont redessinés, et quelles couleurs sont fixes.",{"title":869,"path":870,"stem":871,"icon":353,"description":872,"subcategory":13},"Icônes","\u002Fconventions\u002Ficons","7.conventions\u002F2.icons","Quatre jeux d'icônes, et la seule question qui décide lequel dessine une marque.",{"title":874,"path":875,"stem":876,"icon":91,"description":877,"subcategory":13},"Sécurité des dépendances","\u002Fconventions\u002Fdependency-security","7.conventions\u002F3.dependency-security","Examiner les avis sans masquer les chemins concernés.",{"title":879,"path":880,"stem":881,"children":882,"description":886},"Décisions d’architecture","\u002Fadr","99.adr",[883,887,892,897,902,907,912,917,922,927,932,937],{"title":879,"path":880,"stem":884,"icon":885,"description":886,"subcategory":13},"99.adr\u002Findex","lucide:gavel","Le journal des décisions — chaque décision d’architecture consignée pour duxt.",{"title":888,"path":889,"stem":890,"icon":13,"description":891,"subcategory":13},"Construire duxt comme une couche portant un module","\u002Fadr\u002F0001-build-duxt-as-a-layer-carrying-a-module","99.adr\u002F0001-build-duxt-as-a-layer-carrying-a-module","Distribuer le thème comme une couche Nuxt dont la racine est le paquet, plutôt que comme un modèle de départ.",{"title":893,"path":894,"stem":895,"icon":13,"description":896,"subcategory":13},"Générer les collections à partir d’une seule liste de sources","\u002Fadr\u002F0002-generate-the-collections-from-one-source-list","99.adr\u002F0002-generate-the-collections-from-one-source-list","Calculer les collections Content à partir d’une liste de sources compacte au chargement de la configuration, au lieu de les faire déclarer par les consommateurs.",{"title":898,"path":899,"stem":900,"icon":13,"description":901,"subcategory":13},"Décider les préfixes d’URL à la compilation","\u002Fadr\u002F0003-decide-the-url-prefixes-at-build-time","99.adr\u002F0003-decide-the-url-prefixes-at-build-time","L’apparition d’un segment de dépôt ou de version est tranchée par la liste des sources avant la première requête, jamais par requête.",{"title":903,"path":904,"stem":905,"icon":13,"description":906,"subcategory":13},"Rendre les composants Markdown avec MDC","\u002Fadr\u002F0004-render-markdown-components-with-mdc","99.adr\u002F0004-render-markdown-components-with-mdc","Utiliser la syntaxe MDC propre à Content pour les composants dans le Markdown plutôt que d’adopter MDX.",{"title":908,"path":909,"stem":910,"icon":13,"description":911,"subcategory":13},"Livrer la couche sans liens propres à un propriétaire","\u002Fadr\u002F0005-ship-the-layer-without-owner-specific-links","99.adr\u002F0005-ship-the-layer-without-owner-specific-links","Toute valeur par défaut qui nommerait un projet précis — dépôt, gestionnaire de tickets, communauté, mentions légales — est livrée vide.",{"title":913,"path":914,"stem":915,"icon":13,"description":916,"subcategory":13},"Recompiler de façon planifiée plutôt que rafraîchir à l’exécution","\u002Fadr\u002F0006-rebuild-on-a-schedule-rather-than-refresh-at-runtime","99.adr\u002F0006-rebuild-on-a-schedule-rather-than-refresh-at-runtime","Un site qui lit un autre dépôt en récupère les changements quand il compile, et aucun rafraîchissement à l’exécution n’est proposé.",{"title":918,"path":919,"stem":920,"icon":13,"description":921,"subcategory":13},"Servir les traductions comme des collections à part","\u002Fadr\u002F0007-serve-translations-as-collections-of-their-own","99.adr\u002F0007-serve-translations-as-collections-of-their-own","Ajouter une dimension de locale à une source plutôt qu’un segment de locale au chemin de contenu.",{"title":923,"path":924,"stem":925,"icon":13,"description":926,"subcategory":13},"Bâtir le thème sur des composants shadcn-vue possédés","\u002Fadr\u002F0008-build-the-theme-on-owned-shadcn-vue-components","99.adr\u002F0008-build-the-theme-on-owned-shadcn-vue-components","La couche détient le code source de ses composants d'interface plutôt que de les importer d'une bibliothèque de composants ou d'un thème de documentation tout fait.",{"title":928,"path":929,"stem":930,"icon":13,"description":931,"subcategory":13},"Prendre le socle SEO dans le bundle Nuxt SEO","\u002Fadr\u002F0009-take-the-seo-stack-from-the-nuxt-seo-bundle","99.adr\u002F0009-take-the-seo-stack-from-the-nuxt-seo-bundle","La couche installe @nuxtjs\u002Fseo et lui confie les balises de head et les données structurées qu'elle écrivait à la main, ne gardant que les règles qui dépendent des versions et des traductions.",{"title":933,"path":934,"stem":935,"icon":13,"description":936,"subcategory":13},"Conserver la recherche par collection de Content comme défaut","\u002Fadr\u002F0010-keep-contents-per-collection-search-as-the-default","99.adr\u002F0010-keep-contents-per-collection-search-as-the-default","Un index unique sur toutes les sources a été mesuré face à la recherche à un index par collection de Content et n'est pas le défaut de la couche ; le hook de build en fait plutôt une couche fournisseur.",{"title":938,"path":939,"stem":940,"icon":13,"description":941,"subcategory":13},"Héberger les couches fournisseurs dans un monorepo Turborepo","\u002Fadr\u002F0011-host-the-provider-layers-in-a-turborepo-monorepo","99.adr\u002F0011-host-the-provider-layers-in-a-turborepo-monorepo","La couche passe dans packages\u002Fduxt et le site dans apps\u002Fwww, chaque paquet publié se versionne et s'étiquette seul en \u003Cname>@vX.Y.Z, et la décision de dépôts dédiés consignée dans",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":946},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.39 4.39a1 1 0 0 0 1.68-.474a2.5 2.5 0 1 1 3.014 3.015a1 1 0 0 0-.474 1.68l1.683 1.682a2.414 2.414 0 0 1 0 3.414L19.61 15.39a1 1 0 0 1-1.68-.474a2.5 2.5 0 1 0-3.014 3.015a1 1 0 0 1 .474 1.68l-1.683 1.682a2.414 2.414 0 0 1-3.414 0L8.61 19.61a1 1 0 0 0-1.68.474a2.5 2.5 0 1 1-3.014-3.015a1 1 0 0 0 .474-1.68l-1.683-1.682a2.414 2.414 0 0 1 0-3.414L4.39 8.61a1 1 0 0 1 1.68.474a2.5 2.5 0 1 0 3.014-3.015a1 1 0 0 1-.474-1.68l1.683-1.682a2.414 2.414 0 0 1 3.414 0z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":948},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":950},"\u003Cpath fill=\"currentColor\" d=\"m6.505 18.998l4.434-11.345a4.17 4.17 0 0 1 3.882-2.651h2.674l-4.434 11.345a4.17 4.17 0 0 1-3.883 2.651zm6.505 0l4.434-11.345a4.17 4.17 0 0 1 3.883-2.651H24l-4.434 11.345a4.17 4.17 0 0 1-3.882 2.651zm-13.01 0L4.434 7.653a4.17 4.17 0 0 1 3.882-2.651h2.674L6.556 16.347a4.17 4.17 0 0 1-3.883 2.651z\"\u002F>",{"page":952,"from":2548,"asked":2549},{"id":953,"title":835,"body":954,"breadcrumb":1182,"category":13,"compare":13,"contributors":13,"copyPage":1182,"date":13,"description":838,"extension":2540,"feedback":1182,"fullWidth":945,"icon":103,"lastUpdated":13,"layout":13,"meta":2541,"navigation":1182,"pageInfo":1182,"page_title":13,"path":836,"prevNext":1182,"rawbody":2542,"redirectFrom":2543,"release":13,"search":1182,"seo":2545,"sitemap":2546,"stem":837,"subcategory":13,"toc":13,"__hash__":2547},"docs_fr\u002F5.add-ons\u002F1.typesense.md",{"type":955,"value":956,"toc":2533},"minimark",[957,970,982,987,995,999,1110,1121,1124,2332,2336,2343,2406,2413,2417,2428,2461,2467,2471,2529],[958,959,960,961,965,966,969],"p",{},"duxt émet ",[962,963,964],"a",{"href":260},"un seul hook de build",", et il remet chaque page de\nchaque source, version et langue sous forme d’enregistrements plats. Un site qui\nexploite déjà ",[967,968,835],"strong",{}," en fait une collection à lui — sans re-explorer le\nsite rendu et sans réimplémenter la logique de sources, de versions et de\nlocales de duxt.",[971,972,975],"callout",{"title":973,"type":974},"Le service est le vôtre, pas celui de duxt","info",[958,976,977,978,981],{},"duxt n’embarque aucun SDK Typesense, aucune information d’identification ni configuration de service. La couche complémentaire facultative gère l’intégration ; le service et ses clés restent les vôtres. Sans fournisseur ni écouteur personnalisé, duxt ",[962,979,980],{"href":260},"ne construit aucune charge utile",".",[983,984,986],"h2",{"id":985},"utiliser-la-couche-complémentaire","Utiliser la couche complémentaire",[958,988,989,990,994],{},"Pour l’intégration prête à l’emploi, installe ",[991,992,993],"code",{},"@kirchdev\u002Fduxt-typesense"," et étends-la après duxt. Elle synchronise l’ensemble complet via une collection temporaire et un changement d’alias, supprime la collection précédente gérée et relie le dialogue de recherche existant avec une clé de recherche seule. Les étapes suivantes restent une recette pour une synchronisation personnalisée.",[996,997],"package-managers",{"command":998},"add @kirchdev\u002Fduxt-typesense",[1000,1001,1007],"pre",{"className":1002,"code":1003,"filename":1004,"language":1005,"meta":1006,"style":1006},"language-ts shiki shiki-themes github-light github-dark","export default defineNuxtConfig({\n  extends: ['@kirchdev\u002Fduxt', '@kirchdev\u002Fduxt-typesense'],\n  duxtTypesense: {\n    endpoint: process.env.TYPESENSE_ENDPOINT,\n    collection: 'docs',\n    adminKey: process.env.TYPESENSE_ADMIN_KEY,\n    searchKey: process.env.TYPESENSE_SEARCH_KEY\n  }\n})\n","nuxt.config.ts","ts","",[991,1008,1009,1029,1048,1054,1067,1078,1089,1098,1104],{"__ignoreMap":1006},[1010,1011,1014,1018,1021,1025],"span",{"class":1012,"line":1013},"line",1,[1010,1015,1017],{"class":1016},"szBVR","export",[1010,1019,1020],{"class":1016}," default",[1010,1022,1024],{"class":1023},"sScJk"," defineNuxtConfig",[1010,1026,1028],{"class":1027},"sVt8B","({\n",[1010,1030,1032,1035,1039,1042,1045],{"class":1012,"line":1031},2,[1010,1033,1034],{"class":1027},"  extends: [",[1010,1036,1038],{"class":1037},"sZZnC","'@kirchdev\u002Fduxt'",[1010,1040,1041],{"class":1027},", ",[1010,1043,1044],{"class":1037},"'@kirchdev\u002Fduxt-typesense'",[1010,1046,1047],{"class":1027},"],\n",[1010,1049,1051],{"class":1012,"line":1050},3,[1010,1052,1053],{"class":1027},"  duxtTypesense: {\n",[1010,1055,1057,1060,1064],{"class":1012,"line":1056},4,[1010,1058,1059],{"class":1027},"    endpoint: process.env.",[1010,1061,1063],{"class":1062},"sj4cs","TYPESENSE_ENDPOINT",[1010,1065,1066],{"class":1027},",\n",[1010,1068,1070,1073,1076],{"class":1012,"line":1069},5,[1010,1071,1072],{"class":1027},"    collection: ",[1010,1074,1075],{"class":1037},"'docs'",[1010,1077,1066],{"class":1027},[1010,1079,1081,1084,1087],{"class":1012,"line":1080},6,[1010,1082,1083],{"class":1027},"    adminKey: process.env.",[1010,1085,1086],{"class":1062},"TYPESENSE_ADMIN_KEY",[1010,1088,1066],{"class":1027},[1010,1090,1092,1095],{"class":1012,"line":1091},7,[1010,1093,1094],{"class":1027},"    searchKey: process.env.",[1010,1096,1097],{"class":1062},"TYPESENSE_SEARCH_KEY\n",[1010,1099,1101],{"class":1012,"line":1100},8,[1010,1102,1103],{"class":1027},"  }\n",[1010,1105,1107],{"class":1012,"line":1106},9,[1010,1108,1109],{"class":1027},"})\n",[958,1111,1112,1113,1116,1117,1120],{},"Garde la clé d’administration exclusivement dans la configuration de build. ",[991,1114,1115],{},"searchKey"," doit autoriser uniquement ",[991,1118,1119],{},"documents:search"," pour cet alias, et Typesense doit accepter les requêtes du navigateur depuis ton site.",[983,1122,368],{"id":1123},"étapes",[1125,1126,1127,1141,1144,1152,1336,1343,1363,1380,1392,1662,1669,1682,2156,2163,2174,2186,2320],"steps",{},[1128,1129,1130],"ol",{},[1131,1132,1133,1136,1137,1140],"li",{},[967,1134,1135],{},"Installez le client dans votre site."," C’est une dépendance de build : la\nsynchronisation tourne dans Node pendant ",[991,1138,1139],{},"nuxt build",", jamais dans le\nnavigateur.",[996,1142],{"command":1143},"add -D typesense",[1128,1145,1146],{"start":1031},[1131,1147,1148,1151],{},[967,1149,1150],{},"Déclarez la collection."," Chaque champ d’un enregistrement duxt correspond\nà un champ Typesense, et les deux champs de provenance sont ceux sur\nlesquels un lecteur filtre :",[1000,1153,1156],{"className":1002,"code":1154,"filename":1155,"language":1005,"meta":1006,"style":1006},"import type { CollectionCreateSchema } from 'typesense';\n\nexport const docs: CollectionCreateSchema = {\n  name: 'docs',\n  fields: [\n    { name: 'url', type: 'string' },\n    { name: 'title', type: 'string' },\n    { name: 'content', type: 'string' },\n    { name: 'source', type: 'string', facet: true },\n    { name: 'version', type: 'string', facet: true, optional: true },\n    { name: 'locale', type: 'string', facet: true }\n  ]\n};\n","server\u002Ftypesense-schema.ts",[991,1157,1158,1178,1184,1206,1215,1220,1237,1250,1263,1282,1305,1324,1330],{"__ignoreMap":1006},[1010,1159,1160,1163,1166,1169,1172,1175],{"class":1012,"line":1013},[1010,1161,1162],{"class":1016},"import",[1010,1164,1165],{"class":1016}," type",[1010,1167,1168],{"class":1027}," { CollectionCreateSchema } ",[1010,1170,1171],{"class":1016},"from",[1010,1173,1174],{"class":1037}," 'typesense'",[1010,1176,1177],{"class":1027},";\n",[1010,1179,1180],{"class":1012,"line":1031},[1010,1181,1183],{"emptyLinePlaceholder":1182},true,"\n",[1010,1185,1186,1188,1191,1194,1197,1200,1203],{"class":1012,"line":1050},[1010,1187,1017],{"class":1016},[1010,1189,1190],{"class":1016}," const",[1010,1192,1193],{"class":1062}," docs",[1010,1195,1196],{"class":1016},":",[1010,1198,1199],{"class":1023}," CollectionCreateSchema",[1010,1201,1202],{"class":1016}," =",[1010,1204,1205],{"class":1027}," {\n",[1010,1207,1208,1211,1213],{"class":1012,"line":1056},[1010,1209,1210],{"class":1027},"  name: ",[1010,1212,1075],{"class":1037},[1010,1214,1066],{"class":1027},[1010,1216,1217],{"class":1012,"line":1069},[1010,1218,1219],{"class":1027},"  fields: [\n",[1010,1221,1222,1225,1228,1231,1234],{"class":1012,"line":1080},[1010,1223,1224],{"class":1027},"    { name: ",[1010,1226,1227],{"class":1037},"'url'",[1010,1229,1230],{"class":1027},", type: ",[1010,1232,1233],{"class":1037},"'string'",[1010,1235,1236],{"class":1027}," },\n",[1010,1238,1239,1241,1244,1246,1248],{"class":1012,"line":1091},[1010,1240,1224],{"class":1027},[1010,1242,1243],{"class":1037},"'title'",[1010,1245,1230],{"class":1027},[1010,1247,1233],{"class":1037},[1010,1249,1236],{"class":1027},[1010,1251,1252,1254,1257,1259,1261],{"class":1012,"line":1100},[1010,1253,1224],{"class":1027},[1010,1255,1256],{"class":1037},"'content'",[1010,1258,1230],{"class":1027},[1010,1260,1233],{"class":1037},[1010,1262,1236],{"class":1027},[1010,1264,1265,1267,1270,1272,1274,1277,1280],{"class":1012,"line":1106},[1010,1266,1224],{"class":1027},[1010,1268,1269],{"class":1037},"'source'",[1010,1271,1230],{"class":1027},[1010,1273,1233],{"class":1037},[1010,1275,1276],{"class":1027},", facet: ",[1010,1278,1279],{"class":1062},"true",[1010,1281,1236],{"class":1027},[1010,1283,1285,1287,1290,1292,1294,1296,1298,1301,1303],{"class":1012,"line":1284},10,[1010,1286,1224],{"class":1027},[1010,1288,1289],{"class":1037},"'version'",[1010,1291,1230],{"class":1027},[1010,1293,1233],{"class":1037},[1010,1295,1276],{"class":1027},[1010,1297,1279],{"class":1062},[1010,1299,1300],{"class":1027},", optional: ",[1010,1302,1279],{"class":1062},[1010,1304,1236],{"class":1027},[1010,1306,1308,1310,1313,1315,1317,1319,1321],{"class":1012,"line":1307},11,[1010,1309,1224],{"class":1027},[1010,1311,1312],{"class":1037},"'locale'",[1010,1314,1230],{"class":1027},[1010,1316,1233],{"class":1037},[1010,1318,1276],{"class":1027},[1010,1320,1279],{"class":1062},[1010,1322,1323],{"class":1027}," }\n",[1010,1325,1327],{"class":1012,"line":1326},12,[1010,1328,1329],{"class":1027},"  ]\n",[1010,1331,1333],{"class":1012,"line":1332},13,[1010,1334,1335],{"class":1027},"};\n",[958,1337,1338,1339,1342],{},"Typé en ",[991,1340,1341],{},"CollectionCreateSchema",", car c’est cet objet même que l’étape 4\nremet à Typesense pour créer la collection.",[958,1344,1345,1348,1349,1351,1352,1354,1355,1358,1359,1362],{},[991,1346,1347],{},"id"," n’est pas dans la liste, à dessein : Typesense traite déjà ",[991,1350,1347],{}," comme la\nclé primaire du document, et l’",[991,1353,1347],{}," de duxt est\n",[962,1356,1357],{"href":260},"une empreinte hexadécimale de l’URL"," — valide comme clé,\nidentique sur toutes les machines et inchangée tant que la page reste où elle\nest. C’est ce qui permet à la synchronisation de faire un ",[967,1360,1361],{},"upsert"," plutôt\nqu’une reconstruction.",[958,1364,1365,1368,1369,1372,1373,1376,1377,1379],{},[991,1366,1367],{},"version"," est ",[991,1370,1371],{},"optional",", car une source à une seule version n’en porte\naucune. La version est délibérément retirée de ",[991,1374,1375],{},"source",", pour qu’une facette\nbâtie dessus survive à une publication et que ",[991,1378,1367],{}," à côté soit ce qui\nrestreint à une seule.",[1128,1381,1382],{"start":1050},[1131,1383,1384,1387,1388,1391],{},[967,1385,1386],{},"Écrivez le module qui écoute."," Un module Nuxt dans votre propre site est\ntoute l’intégration — ",[991,1389,1390],{},"defineNuxtModule",", un hook, un import :",[1000,1393,1396],{"className":1002,"code":1394,"filename":1395,"language":1005,"meta":1006,"style":1006},"import { defineNuxtModule } from '@nuxt\u002Fkit';\nimport { Client } from 'typesense';\nimport type { DuxtSearchRecord } from '@kirchdev\u002Fduxt\u002Fsearch-records';\nimport { docs } from '..\u002Fserver\u002Ftypesense-schema';\n\nexport default defineNuxtModule({\n  meta: { name: 'typesense-sync' },\n  setup(_options, nuxt) {\n    const key = process.env.TYPESENSE_ADMIN_KEY;\n    \u002F\u002F Pas de clé, c’est un build local, pas un échec : on saute plutôt que\n    \u002F\u002F de le casser.\n    if (!key) return;\n\n    nuxt.hook('duxt:search:records', async (records) => {\n      const client = new Client({\n        nodes: [{ url: process.env.TYPESENSE_URL! }],\n        apiKey: key\n      });\n\n      await sync(client, records);\n    });\n  }\n});\n","modules\u002Ftypesense.ts",[991,1397,1398,1412,1425,1441,1455,1459,1470,1480,1500,1517,1523,1528,1547,1551,1583,1602,1616,1622,1628,1633,1645,1651,1656],{"__ignoreMap":1006},[1010,1399,1400,1402,1405,1407,1410],{"class":1012,"line":1013},[1010,1401,1162],{"class":1016},[1010,1403,1404],{"class":1027}," { defineNuxtModule } ",[1010,1406,1171],{"class":1016},[1010,1408,1409],{"class":1037}," '@nuxt\u002Fkit'",[1010,1411,1177],{"class":1027},[1010,1413,1414,1416,1419,1421,1423],{"class":1012,"line":1031},[1010,1415,1162],{"class":1016},[1010,1417,1418],{"class":1027}," { Client } ",[1010,1420,1171],{"class":1016},[1010,1422,1174],{"class":1037},[1010,1424,1177],{"class":1027},[1010,1426,1427,1429,1431,1434,1436,1439],{"class":1012,"line":1050},[1010,1428,1162],{"class":1016},[1010,1430,1165],{"class":1016},[1010,1432,1433],{"class":1027}," { DuxtSearchRecord } ",[1010,1435,1171],{"class":1016},[1010,1437,1438],{"class":1037}," '@kirchdev\u002Fduxt\u002Fsearch-records'",[1010,1440,1177],{"class":1027},[1010,1442,1443,1445,1448,1450,1453],{"class":1012,"line":1056},[1010,1444,1162],{"class":1016},[1010,1446,1447],{"class":1027}," { docs } ",[1010,1449,1171],{"class":1016},[1010,1451,1452],{"class":1037}," '..\u002Fserver\u002Ftypesense-schema'",[1010,1454,1177],{"class":1027},[1010,1456,1457],{"class":1012,"line":1069},[1010,1458,1183],{"emptyLinePlaceholder":1182},[1010,1460,1461,1463,1465,1468],{"class":1012,"line":1080},[1010,1462,1017],{"class":1016},[1010,1464,1020],{"class":1016},[1010,1466,1467],{"class":1023}," defineNuxtModule",[1010,1469,1028],{"class":1027},[1010,1471,1472,1475,1478],{"class":1012,"line":1091},[1010,1473,1474],{"class":1027},"  meta: { name: ",[1010,1476,1477],{"class":1037},"'typesense-sync'",[1010,1479,1236],{"class":1027},[1010,1481,1482,1485,1488,1492,1494,1497],{"class":1012,"line":1100},[1010,1483,1484],{"class":1023},"  setup",[1010,1486,1487],{"class":1027},"(",[1010,1489,1491],{"class":1490},"s4XuR","_options",[1010,1493,1041],{"class":1027},[1010,1495,1496],{"class":1490},"nuxt",[1010,1498,1499],{"class":1027},") {\n",[1010,1501,1502,1505,1508,1510,1513,1515],{"class":1012,"line":1106},[1010,1503,1504],{"class":1016},"    const",[1010,1506,1507],{"class":1062}," key",[1010,1509,1202],{"class":1016},[1010,1511,1512],{"class":1027}," process.env.",[1010,1514,1086],{"class":1062},[1010,1516,1177],{"class":1027},[1010,1518,1519],{"class":1012,"line":1284},[1010,1520,1522],{"class":1521},"sJ8bj","    \u002F\u002F Pas de clé, c’est un build local, pas un échec : on saute plutôt que\n",[1010,1524,1525],{"class":1012,"line":1307},[1010,1526,1527],{"class":1521},"    \u002F\u002F de le casser.\n",[1010,1529,1530,1533,1536,1539,1542,1545],{"class":1012,"line":1326},[1010,1531,1532],{"class":1016},"    if",[1010,1534,1535],{"class":1027}," (",[1010,1537,1538],{"class":1016},"!",[1010,1540,1541],{"class":1027},"key) ",[1010,1543,1544],{"class":1016},"return",[1010,1546,1177],{"class":1027},[1010,1548,1549],{"class":1012,"line":1332},[1010,1550,1183],{"emptyLinePlaceholder":1182},[1010,1552,1554,1557,1560,1562,1565,1567,1570,1572,1575,1578,1581],{"class":1012,"line":1553},14,[1010,1555,1556],{"class":1027},"    nuxt.",[1010,1558,1559],{"class":1023},"hook",[1010,1561,1487],{"class":1027},[1010,1563,1564],{"class":1037},"'duxt:search:records'",[1010,1566,1041],{"class":1027},[1010,1568,1569],{"class":1016},"async",[1010,1571,1535],{"class":1027},[1010,1573,1574],{"class":1490},"records",[1010,1576,1577],{"class":1027},") ",[1010,1579,1580],{"class":1016},"=>",[1010,1582,1205],{"class":1027},[1010,1584,1586,1589,1592,1594,1597,1600],{"class":1012,"line":1585},15,[1010,1587,1588],{"class":1016},"      const",[1010,1590,1591],{"class":1062}," client",[1010,1593,1202],{"class":1016},[1010,1595,1596],{"class":1016}," new",[1010,1598,1599],{"class":1023}," Client",[1010,1601,1028],{"class":1027},[1010,1603,1605,1608,1611,1613],{"class":1012,"line":1604},16,[1010,1606,1607],{"class":1027},"        nodes: [{ url: process.env.",[1010,1609,1610],{"class":1062},"TYPESENSE_URL",[1010,1612,1538],{"class":1016},[1010,1614,1615],{"class":1027}," }],\n",[1010,1617,1619],{"class":1012,"line":1618},17,[1010,1620,1621],{"class":1027},"        apiKey: key\n",[1010,1623,1625],{"class":1012,"line":1624},18,[1010,1626,1627],{"class":1027},"      });\n",[1010,1629,1631],{"class":1012,"line":1630},19,[1010,1632,1183],{"emptyLinePlaceholder":1182},[1010,1634,1636,1639,1642],{"class":1012,"line":1635},20,[1010,1637,1638],{"class":1016},"      await",[1010,1640,1641],{"class":1023}," sync",[1010,1643,1644],{"class":1027},"(client, records);\n",[1010,1646,1648],{"class":1012,"line":1647},21,[1010,1649,1650],{"class":1027},"    });\n",[1010,1652,1654],{"class":1012,"line":1653},22,[1010,1655,1103],{"class":1027},[1010,1657,1659],{"class":1012,"line":1658},23,[1010,1660,1661],{"class":1027},"});\n",[958,1663,1664,1665,1668],{},"La charge utile est ",[967,1666,1667],{},"gelée",". Transformez-la en documents à vous — ne\nréécrivez jamais un enregistrement et ne triez pas le tableau sur place, car\ntous les autres auditeurs reçoivent les mêmes objets.",[1128,1670,1671],{"start":1056},[1131,1672,1673,1676,1677,1681],{},[967,1674,1675],{},"Synchronisez l’ensemble complet, et retirez ce qui a disparu."," Le hook\nremet l’ensemble ",[1678,1679,1680],"em",{},"complet"," et courant à chaque build : l’ensemble est donc\nlui-même l’instruction — tout ce que la collection contient et qui n’y figure\npas a été supprimé, déplacé ou renommé :",[1000,1683,1685],{"className":1002,"code":1684,"filename":1395,"language":1005,"meta":1006,"style":1006},"async function sync(client: Client, records: readonly DuxtSearchRecord[]) {\n  const collection = client.collections(docs.name);\n\n  \u002F\u002F Typesense ne crée rien implicitement : importer dans une collection\n  \u002F\u002F qui n’existe pas échoue net, c’est donc le premier build qui la crée.\n  if (!(await collection.exists())) await client.collections().create(docs);\n\n  await collection.documents().import(\n    records.map((record) => ({ ...record })),\n    { action: 'upsert' }\n  );\n\n  \u002F\u002F Tout ce que le build n’a pas remis n’est plus sur le site.\n  const kept = new Set(records.map((record) => record.id));\n  const live = await collection.documents().export();\n\n  const stale = live\n    .split('\\n')\n    .filter(Boolean)\n    .map((line) => JSON.parse(line).id as string)\n    .filter((id) => !kept.has(id));\n\n  \u002F\u002F Supprimez par lots : chaque id entre dans la chaîne du filtre, et un\n  \u002F\u002F seul gros renommage en bâtirait un que Typesense refuse.\n  for (let index = 0; index \u003C stale.length; index += 100) {\n    const batch = stale.slice(index, index + 100).join(',');\n    await collection.documents().delete({ filter_by: `id:[${batch}]` });\n  }\n}\n",[991,1686,1687,1720,1739,1743,1748,1753,1791,1795,1812,1839,1849,1854,1858,1863,1893,1916,1920,1932,1953,1963,1996,2022,2026,2031,2036,2078,2115,2145,2150],{"__ignoreMap":1006},[1010,1688,1689,1691,1694,1696,1698,1701,1703,1705,1707,1709,1711,1714,1717],{"class":1012,"line":1013},[1010,1690,1569],{"class":1016},[1010,1692,1693],{"class":1016}," function",[1010,1695,1641],{"class":1023},[1010,1697,1487],{"class":1027},[1010,1699,1700],{"class":1490},"client",[1010,1702,1196],{"class":1016},[1010,1704,1599],{"class":1023},[1010,1706,1041],{"class":1027},[1010,1708,1574],{"class":1490},[1010,1710,1196],{"class":1016},[1010,1712,1713],{"class":1016}," readonly",[1010,1715,1716],{"class":1023}," DuxtSearchRecord",[1010,1718,1719],{"class":1027},"[]) {\n",[1010,1721,1722,1725,1728,1730,1733,1736],{"class":1012,"line":1031},[1010,1723,1724],{"class":1016},"  const",[1010,1726,1727],{"class":1062}," collection",[1010,1729,1202],{"class":1016},[1010,1731,1732],{"class":1027}," client.",[1010,1734,1735],{"class":1023},"collections",[1010,1737,1738],{"class":1027},"(docs.name);\n",[1010,1740,1741],{"class":1012,"line":1050},[1010,1742,1183],{"emptyLinePlaceholder":1182},[1010,1744,1745],{"class":1012,"line":1056},[1010,1746,1747],{"class":1521},"  \u002F\u002F Typesense ne crée rien implicitement : importer dans une collection\n",[1010,1749,1750],{"class":1012,"line":1069},[1010,1751,1752],{"class":1521},"  \u002F\u002F qui n’existe pas échoue net, c’est donc le premier build qui la crée.\n",[1010,1754,1755,1758,1760,1762,1764,1767,1770,1773,1776,1778,1780,1782,1785,1788],{"class":1012,"line":1080},[1010,1756,1757],{"class":1016},"  if",[1010,1759,1535],{"class":1027},[1010,1761,1538],{"class":1016},[1010,1763,1487],{"class":1027},[1010,1765,1766],{"class":1016},"await",[1010,1768,1769],{"class":1027}," collection.",[1010,1771,1772],{"class":1023},"exists",[1010,1774,1775],{"class":1027},"())) ",[1010,1777,1766],{"class":1016},[1010,1779,1732],{"class":1027},[1010,1781,1735],{"class":1023},[1010,1783,1784],{"class":1027},"().",[1010,1786,1787],{"class":1023},"create",[1010,1789,1790],{"class":1027},"(docs);\n",[1010,1792,1793],{"class":1012,"line":1091},[1010,1794,1183],{"emptyLinePlaceholder":1182},[1010,1796,1797,1800,1802,1805,1807,1809],{"class":1012,"line":1100},[1010,1798,1799],{"class":1016},"  await",[1010,1801,1769],{"class":1027},[1010,1803,1804],{"class":1023},"documents",[1010,1806,1784],{"class":1027},[1010,1808,1162],{"class":1023},[1010,1810,1811],{"class":1027},"(\n",[1010,1813,1814,1817,1820,1823,1826,1828,1830,1833,1836],{"class":1012,"line":1106},[1010,1815,1816],{"class":1027},"    records.",[1010,1818,1819],{"class":1023},"map",[1010,1821,1822],{"class":1027},"((",[1010,1824,1825],{"class":1490},"record",[1010,1827,1577],{"class":1027},[1010,1829,1580],{"class":1016},[1010,1831,1832],{"class":1027}," ({ ",[1010,1834,1835],{"class":1016},"...",[1010,1837,1838],{"class":1027},"record })),\n",[1010,1840,1841,1844,1847],{"class":1012,"line":1284},[1010,1842,1843],{"class":1027},"    { action: ",[1010,1845,1846],{"class":1037},"'upsert'",[1010,1848,1323],{"class":1027},[1010,1850,1851],{"class":1012,"line":1307},[1010,1852,1853],{"class":1027},"  );\n",[1010,1855,1856],{"class":1012,"line":1326},[1010,1857,1183],{"emptyLinePlaceholder":1182},[1010,1859,1860],{"class":1012,"line":1332},[1010,1861,1862],{"class":1521},"  \u002F\u002F Tout ce que le build n’a pas remis n’est plus sur le site.\n",[1010,1864,1865,1867,1870,1872,1874,1877,1880,1882,1884,1886,1888,1890],{"class":1012,"line":1553},[1010,1866,1724],{"class":1016},[1010,1868,1869],{"class":1062}," kept",[1010,1871,1202],{"class":1016},[1010,1873,1596],{"class":1016},[1010,1875,1876],{"class":1023}," Set",[1010,1878,1879],{"class":1027},"(records.",[1010,1881,1819],{"class":1023},[1010,1883,1822],{"class":1027},[1010,1885,1825],{"class":1490},[1010,1887,1577],{"class":1027},[1010,1889,1580],{"class":1016},[1010,1891,1892],{"class":1027}," record.id));\n",[1010,1894,1895,1897,1900,1902,1905,1907,1909,1911,1913],{"class":1012,"line":1585},[1010,1896,1724],{"class":1016},[1010,1898,1899],{"class":1062}," live",[1010,1901,1202],{"class":1016},[1010,1903,1904],{"class":1016}," await",[1010,1906,1769],{"class":1027},[1010,1908,1804],{"class":1023},[1010,1910,1784],{"class":1027},[1010,1912,1017],{"class":1023},[1010,1914,1915],{"class":1027},"();\n",[1010,1917,1918],{"class":1012,"line":1604},[1010,1919,1183],{"emptyLinePlaceholder":1182},[1010,1921,1922,1924,1927,1929],{"class":1012,"line":1618},[1010,1923,1724],{"class":1016},[1010,1925,1926],{"class":1062}," stale",[1010,1928,1202],{"class":1016},[1010,1930,1931],{"class":1027}," live\n",[1010,1933,1934,1937,1940,1942,1945,1948,1950],{"class":1012,"line":1624},[1010,1935,1936],{"class":1027},"    .",[1010,1938,1939],{"class":1023},"split",[1010,1941,1487],{"class":1027},[1010,1943,1944],{"class":1037},"'",[1010,1946,1947],{"class":1062},"\\n",[1010,1949,1944],{"class":1037},[1010,1951,1952],{"class":1027},")\n",[1010,1954,1955,1957,1960],{"class":1012,"line":1630},[1010,1956,1936],{"class":1027},[1010,1958,1959],{"class":1023},"filter",[1010,1961,1962],{"class":1027},"(Boolean)\n",[1010,1964,1965,1967,1969,1971,1973,1975,1977,1980,1982,1985,1988,1991,1994],{"class":1012,"line":1635},[1010,1966,1936],{"class":1027},[1010,1968,1819],{"class":1023},[1010,1970,1822],{"class":1027},[1010,1972,1012],{"class":1490},[1010,1974,1577],{"class":1027},[1010,1976,1580],{"class":1016},[1010,1978,1979],{"class":1062}," JSON",[1010,1981,981],{"class":1027},[1010,1983,1984],{"class":1023},"parse",[1010,1986,1987],{"class":1027},"(line).id ",[1010,1989,1990],{"class":1016},"as",[1010,1992,1993],{"class":1062}," string",[1010,1995,1952],{"class":1027},[1010,1997,1998,2000,2002,2004,2006,2008,2010,2013,2016,2019],{"class":1012,"line":1647},[1010,1999,1936],{"class":1027},[1010,2001,1959],{"class":1023},[1010,2003,1822],{"class":1027},[1010,2005,1347],{"class":1490},[1010,2007,1577],{"class":1027},[1010,2009,1580],{"class":1016},[1010,2011,2012],{"class":1016}," !",[1010,2014,2015],{"class":1027},"kept.",[1010,2017,2018],{"class":1023},"has",[1010,2020,2021],{"class":1027},"(id));\n",[1010,2023,2024],{"class":1012,"line":1653},[1010,2025,1183],{"emptyLinePlaceholder":1182},[1010,2027,2028],{"class":1012,"line":1658},[1010,2029,2030],{"class":1521},"  \u002F\u002F Supprimez par lots : chaque id entre dans la chaîne du filtre, et un\n",[1010,2032,2033],{"class":1012,"line":944},[1010,2034,2035],{"class":1521},"  \u002F\u002F seul gros renommage en bâtirait un que Typesense refuse.\n",[1010,2037,2039,2042,2044,2047,2050,2053,2056,2059,2062,2065,2068,2070,2073,2076],{"class":1012,"line":2038},25,[1010,2040,2041],{"class":1016},"  for",[1010,2043,1535],{"class":1027},[1010,2045,2046],{"class":1016},"let",[1010,2048,2049],{"class":1027}," index ",[1010,2051,2052],{"class":1016},"=",[1010,2054,2055],{"class":1062}," 0",[1010,2057,2058],{"class":1027},"; index ",[1010,2060,2061],{"class":1016},"\u003C",[1010,2063,2064],{"class":1027}," stale.",[1010,2066,2067],{"class":1062},"length",[1010,2069,2058],{"class":1027},[1010,2071,2072],{"class":1016},"+=",[1010,2074,2075],{"class":1062}," 100",[1010,2077,1499],{"class":1027},[1010,2079,2081,2083,2086,2088,2090,2093,2096,2099,2101,2104,2107,2109,2112],{"class":1012,"line":2080},26,[1010,2082,1504],{"class":1016},[1010,2084,2085],{"class":1062}," batch",[1010,2087,1202],{"class":1016},[1010,2089,2064],{"class":1027},[1010,2091,2092],{"class":1023},"slice",[1010,2094,2095],{"class":1027},"(index, index ",[1010,2097,2098],{"class":1016},"+",[1010,2100,2075],{"class":1062},[1010,2102,2103],{"class":1027},").",[1010,2105,2106],{"class":1023},"join",[1010,2108,1487],{"class":1027},[1010,2110,2111],{"class":1037},"','",[1010,2113,2114],{"class":1027},");\n",[1010,2116,2118,2121,2123,2125,2127,2130,2133,2136,2139,2142],{"class":1012,"line":2117},27,[1010,2119,2120],{"class":1016},"    await",[1010,2122,1769],{"class":1027},[1010,2124,1804],{"class":1023},[1010,2126,1784],{"class":1027},[1010,2128,2129],{"class":1023},"delete",[1010,2131,2132],{"class":1027},"({ filter_by: ",[1010,2134,2135],{"class":1037},"`id:[${",[1010,2137,2138],{"class":1027},"batch",[1010,2140,2141],{"class":1037},"}]`",[1010,2143,2144],{"class":1027}," });\n",[1010,2146,2148],{"class":1012,"line":2147},28,[1010,2149,1103],{"class":1027},[1010,2151,2153],{"class":1012,"line":2152},29,[1010,2154,2155],{"class":1027},"}\n",[958,2157,2158,2159,2162],{},"La collection est créée au premier passage puis laissée telle quelle, et les\nids périmés sont supprimés ",[967,2160,2161],{},"par lots"," — Typesense prend le filtre comme une\nseule chaîne, et un renommage déplaçant une source entière en bâtirait\nautrement un qu’il refuse.",[971,2164,2167],{"title":2165,"type":2166},"Ou échangez plutôt un alias","tip",[958,2168,2169,2170,2173],{},"Importez dans une collection nommée d’après le build, pointez un ",[967,2171,2172],{},"alias","\nTypesense dessus, puis jetez la précédente. Chaque build crée sa propre\ncollection : ni la vérification d’existence ni la suppression par lots ne\nsont nécessaires, et les lecteurs ne voient jamais un index à moitié écrit —\nau prix d’une réindexation complète à chaque build plutôt que du seul delta.",[1128,2175,2176],{"start":1069},[1131,2177,2178,2181,2182,2185],{},[967,2179,2180],{},"Cherchez depuis le navigateur avec une clé de recherche seule."," La clé\nd’administration ci-dessus signe les écritures et ne doit jamais atteindre\nune page. Émettez une clé ",[967,2183,2184],{},"restreinte, en lecture de recherche seule"," pour\nle client, et filtrez sur les facettes que le schéma a déclarées :",[1000,2187,2189],{"className":1002,"code":2188,"language":1005,"meta":1006,"style":1006},"\u002F\u002F `locale` est la langue du CONTENU, pas la langue de l’interface.\n\u002F\u002F `version` est absente d’une source sans versions : la clause ne s’ajoute\n\u002F\u002F que s’il y en a une ; figée, elle filtrerait sur `undefined`.\nconst filters = [`locale:${locale}`];\nif (version) filters.push(`version:${version}`);\n\nconst results = await client.collections('docs').documents().search({\n  q: query,\n  query_by: 'title,content',\n  filter_by: filters.join(' && ')\n});\n",[991,2190,2191,2196,2201,2206,2231,2253,2257,2287,2292,2302,2316],{"__ignoreMap":1006},[1010,2192,2193],{"class":1012,"line":1013},[1010,2194,2195],{"class":1521},"\u002F\u002F `locale` est la langue du CONTENU, pas la langue de l’interface.\n",[1010,2197,2198],{"class":1012,"line":1031},[1010,2199,2200],{"class":1521},"\u002F\u002F `version` est absente d’une source sans versions : la clause ne s’ajoute\n",[1010,2202,2203],{"class":1012,"line":1050},[1010,2204,2205],{"class":1521},"\u002F\u002F que s’il y en a une ; figée, elle filtrerait sur `undefined`.\n",[1010,2207,2208,2211,2214,2216,2219,2222,2225,2228],{"class":1012,"line":1056},[1010,2209,2210],{"class":1016},"const",[1010,2212,2213],{"class":1062}," filters",[1010,2215,1202],{"class":1016},[1010,2217,2218],{"class":1027}," [",[1010,2220,2221],{"class":1037},"`locale:${",[1010,2223,2224],{"class":1027},"locale",[1010,2226,2227],{"class":1037},"}`",[1010,2229,2230],{"class":1027},"];\n",[1010,2232,2233,2236,2239,2242,2244,2247,2249,2251],{"class":1012,"line":1069},[1010,2234,2235],{"class":1016},"if",[1010,2237,2238],{"class":1027}," (version) filters.",[1010,2240,2241],{"class":1023},"push",[1010,2243,1487],{"class":1027},[1010,2245,2246],{"class":1037},"`version:${",[1010,2248,1367],{"class":1027},[1010,2250,2227],{"class":1037},[1010,2252,2114],{"class":1027},[1010,2254,2255],{"class":1012,"line":1080},[1010,2256,1183],{"emptyLinePlaceholder":1182},[1010,2258,2259,2261,2264,2266,2268,2270,2272,2274,2276,2278,2280,2282,2285],{"class":1012,"line":1091},[1010,2260,2210],{"class":1016},[1010,2262,2263],{"class":1062}," results",[1010,2265,1202],{"class":1016},[1010,2267,1904],{"class":1016},[1010,2269,1732],{"class":1027},[1010,2271,1735],{"class":1023},[1010,2273,1487],{"class":1027},[1010,2275,1075],{"class":1037},[1010,2277,2103],{"class":1027},[1010,2279,1804],{"class":1023},[1010,2281,1784],{"class":1027},[1010,2283,2284],{"class":1023},"search",[1010,2286,1028],{"class":1027},[1010,2288,2289],{"class":1012,"line":1100},[1010,2290,2291],{"class":1027},"  q: query,\n",[1010,2293,2294,2297,2300],{"class":1012,"line":1106},[1010,2295,2296],{"class":1027},"  query_by: ",[1010,2298,2299],{"class":1037},"'title,content'",[1010,2301,1066],{"class":1027},[1010,2303,2304,2307,2309,2311,2314],{"class":1012,"line":1284},[1010,2305,2306],{"class":1027},"  filter_by: filters.",[1010,2308,2106],{"class":1023},[1010,2310,1487],{"class":1027},[1010,2312,2313],{"class":1037},"' && '",[1010,2315,1952],{"class":1027},[1010,2317,2318],{"class":1012,"line":1307},[1010,2319,1661],{"class":1027},[1128,2321,2322],{"start":1080},[1131,2323,2324,2327,2328,2331],{},[967,2325,2326],{},"Vérifiez un build de bout en bout."," Lancez un build avec la clé, et\nconfirmez que la collection contient un enregistrement pour une page dans\n",[967,2329,2330],{},"chaque"," source, version et langue que le site sert — pas seulement la\nlangue par défaut. Le premier build crée la collection ; chacun d’après fait\nun upsert dans la même.",[983,2333,2335],{"id":2334},"ce-que-les-enregistrements-règlent-déjà-pour-vous","Ce que les enregistrements règlent déjà pour vous",[958,2337,2338,2339,2342],{},"Quatre propriétés de la charge utile rendent une synchronisation aussi courte\ncorrecte, et toutes les quatre relèvent du\n",[962,2340,2341],{"href":260},"contrat du hook",", non du conseil de ce guide :",[2344,2345,2346,2360],"table",{},[2347,2348,2349],"thead",{},[2350,2351,2352,2357],"tr",{},[2353,2354,2356],"th",{"align":2355},"left","Propriété",[2353,2358,2359],{"align":2355},"Ce qu’elle apporte à la synchronisation",[2361,2362,2363,2380,2390,2398],"tbody",{},[2350,2364,2365,2374],{},[2366,2367,2368,2370,2371],"td",{"align":2355},[991,2369,1347],{}," dérive de ",[991,2372,2373],{},"url",[2366,2375,2376,2377,2379],{"align":2355},"Une clé primaire stable : ",[991,2378,1361],{}," suffit, une reconstruction n’est jamais nécessaire",[2350,2381,2382,2387],{},[2366,2383,2384,2385],{"align":2355},"La charge utile est l’ensemble ",[967,2386,1680],{},[2366,2388,2389],{"align":2355},"Supprimer, c’est comparer à un build, sans exploration ni comptabilité",[2350,2391,2392,2395],{},[2366,2393,2394],{"align":2355},"duxt ne se déclenche pas sur une analyse vide",[2366,2396,2397],{"align":2355},"Un build qui n’a rien analysé ne peut jamais vous dire de vider l’index",[2350,2399,2400,2403],{},[2366,2401,2402],{"align":2355},"L’ordre est déterministe",[2366,2404,2405],{"align":2355},"Deux builds diffèrent exactement là où le site a différé",[958,2407,2408,2409,2412],{},"Une page qui a écrit ",[991,2410,2411],{},"search: false",", et une traduction dans une langue que le\nsite ne route pas, ne produisent aucun enregistrement — donc ni l’une ni l’autre\nn’atteint Typesense.",[983,2414,2416],{"id":2415},"en-faire-un-paquet","En faire un paquet",[958,2418,2419,2420,2423,2424,2427],{},"Le module ci-dessus fait ~40 lignes et appartient à un site. Dès qu’un deuxième\nsite en a besoin, la façon de le partager est ",[967,2421,2422],{},"une couche Nuxt",", pas un\nplugin : une couche porte le module, ses valeurs ",[991,2425,2426],{},"app.config"," par défaut et ses\ncomposants dans un paquet versionné, et un consommateur l’ajoute à côté de duxt.",[1000,2429,2431],{"className":1002,"code":2430,"filename":1004,"language":1005,"meta":1006,"style":1006},"export default defineNuxtConfig({\n  extends: ['@kirchdev\u002Fduxt', 'duxt-typesense']\n});\n",[991,2432,2433,2443,2457],{"__ignoreMap":1006},[1010,2434,2435,2437,2439,2441],{"class":1012,"line":1013},[1010,2436,1017],{"class":1016},[1010,2438,1020],{"class":1016},[1010,2440,1024],{"class":1023},[1010,2442,1028],{"class":1027},[1010,2444,2445,2447,2449,2451,2454],{"class":1012,"line":1031},[1010,2446,1034],{"class":1027},[1010,2448,1038],{"class":1037},[1010,2450,1041],{"class":1027},[1010,2452,2453],{"class":1037},"'duxt-typesense'",[1010,2455,2456],{"class":1027},"]\n",[1010,2458,2459],{"class":1012,"line":1050},[1010,2460,1661],{"class":1027},[958,2462,2463,2464,981],{},"Cette couche possède les informations d’identification, la configuration du\nservice, la politique de synchronisation et l’interface de recherche côté\nnavigateur. duxt n’en gagne aucune —\n",[962,2465,2466],{"href":260},"c’est toute la raison de la forme du hook",[983,2468,2470],{"id":2469},"liste-de-contrôle","Liste de contrôle",[2472,2473,2476,2489,2495,2508,2517,2523],"ul",{"className":2474},[2475],"contains-task-list",[1131,2477,2480,2484,2485,2488],{"className":2478},[2479],"task-list-item",[2481,2482],"input",{"disabled":1182,"type":2483},"checkbox"," Le client est une dépendance de ",[967,2486,2487],{},"votre"," site, pas de la couche",[1131,2490,2492,2494],{"className":2491},[2479],[2481,2493],{"disabled":1182,"type":2483}," La clé d’administration vit dans l’environnement de build et n’atteint jamais une page",[1131,2496,2498,2500,2501,1041,2503,2505,2506],{"className":2497},[2479],[2481,2499],{"disabled":1182,"type":2483}," La collection est créée au premier build et facette ",[991,2502,1375],{},[991,2504,1367],{}," et ",[991,2507,2224],{},[1131,2509,2511,2513,2514,2516],{"className":2510},[2479],[2481,2512],{"disabled":1182,"type":2483}," Les enregistrements qui ne sont plus remis sont retirés — par comparaison ",[967,2515,2161],{}," ou par échange d’alias",[1131,2518,2520,2522],{"className":2519},[2479],[2481,2521],{"disabled":1182,"type":2483}," Un build sans la clé saute la synchronisation au lieu d’échouer",[1131,2524,2526,2528],{"className":2525},[2479],[2481,2527],{"disabled":1182,"type":2483}," Chaque source, version et langue est représentée dans la collection",[2530,2531,2532],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":1006,"searchDepth":1031,"depth":1069,"links":2534},[2535,2536,2537,2538,2539],{"id":985,"depth":1031,"text":986},{"id":1123,"depth":1031,"text":368},{"id":2334,"depth":1031,"text":2335},{"id":2415,"depth":1031,"text":2416},{"id":2469,"depth":1031,"text":2470},"md",{},"---\ntitle: Typesense\ndescription: Consommez l’unique hook de build de duxt dans une collection Typesense — chaque source, version et langue, mise à jour par un id stable.\nicon: lucide:search\nredirectFrom:\n  - \u002Fguides\u002Fsend-your-pages-to-typesense\n---\n\nduxt émet [un seul hook de build](\u002Freference\u002Fhooks), et il remet chaque page de\nchaque source, version et langue sous forme d’enregistrements plats. Un site qui\nexploite déjà **Typesense** en fait une collection à lui — sans re-explorer le\nsite rendu et sans réimplémenter la logique de sources, de versions et de\nlocales de duxt.\n\n::callout{type=\"info\" title=\"Le service est le vôtre, pas celui de duxt\"}\nduxt n’embarque aucun SDK Typesense, aucune information d’identification ni configuration de service. La couche complémentaire facultative gère l’intégration ; le service et ses clés restent les vôtres. Sans fournisseur ni écouteur personnalisé, duxt [ne construit aucune charge utile](\u002Freference\u002Fhooks).\n::\n\n## Utiliser la couche complémentaire\n\nPour l’intégration prête à l’emploi, installe `@kirchdev\u002Fduxt-typesense` et étends-la après duxt. Elle synchronise l’ensemble complet via une collection temporaire et un changement d’alias, supprime la collection précédente gérée et relie le dialogue de recherche existant avec une clé de recherche seule. Les étapes suivantes restent une recette pour une synchronisation personnalisée.\n\n::package-managers{command=\"add @kirchdev\u002Fduxt-typesense\"}\n::\n\n```ts [nuxt.config.ts]\nexport default defineNuxtConfig({\n  extends: ['@kirchdev\u002Fduxt', '@kirchdev\u002Fduxt-typesense'],\n  duxtTypesense: {\n    endpoint: process.env.TYPESENSE_ENDPOINT,\n    collection: 'docs',\n    adminKey: process.env.TYPESENSE_ADMIN_KEY,\n    searchKey: process.env.TYPESENSE_SEARCH_KEY\n  }\n})\n```\n\nGarde la clé d’administration exclusivement dans la configuration de build. `searchKey` doit autoriser uniquement `documents:search` pour cet alias, et Typesense doit accepter les requêtes du navigateur depuis ton site.\n\n## Étapes\n\n::steps\n\n1. **Installez le client dans votre site.** C’est une dépendance de build : la\n   synchronisation tourne dans Node pendant `nuxt build`, jamais dans le\n   navigateur.\n\n   ::package-managers{command=\"add -D typesense\"}\n   ::\n\n2. **Déclarez la collection.** Chaque champ d’un enregistrement duxt correspond\n   à un champ Typesense, et les deux champs de provenance sont ceux sur\n   lesquels un lecteur filtre :\n\n   ```ts [server\u002Ftypesense-schema.ts]\n   import type { CollectionCreateSchema } from 'typesense';\n\n   export const docs: CollectionCreateSchema = {\n     name: 'docs',\n     fields: [\n       { name: 'url', type: 'string' },\n       { name: 'title', type: 'string' },\n       { name: 'content', type: 'string' },\n       { name: 'source', type: 'string', facet: true },\n       { name: 'version', type: 'string', facet: true, optional: true },\n       { name: 'locale', type: 'string', facet: true }\n     ]\n   };\n   ```\n\n   Typé en `CollectionCreateSchema`, car c’est cet objet même que l’étape 4\n   remet à Typesense pour créer la collection.\n\n   `id` n’est pas dans la liste, à dessein : Typesense traite déjà `id` comme la\n   clé primaire du document, et l’`id` de duxt est\n   [une empreinte hexadécimale de l’URL](\u002Freference\u002Fhooks) — valide comme clé,\n   identique sur toutes les machines et inchangée tant que la page reste où elle\n   est. C’est ce qui permet à la synchronisation de faire un **upsert** plutôt\n   qu’une reconstruction.\n\n   `version` est `optional`, car une source à une seule version n’en porte\n   aucune. La version est délibérément retirée de `source`, pour qu’une facette\n   bâtie dessus survive à une publication et que `version` à côté soit ce qui\n   restreint à une seule.\n\n3. **Écrivez le module qui écoute.** Un module Nuxt dans votre propre site est\n   toute l’intégration — `defineNuxtModule`, un hook, un import :\n\n   ```ts [modules\u002Ftypesense.ts]\n   import { defineNuxtModule } from '@nuxt\u002Fkit';\n   import { Client } from 'typesense';\n   import type { DuxtSearchRecord } from '@kirchdev\u002Fduxt\u002Fsearch-records';\n   import { docs } from '..\u002Fserver\u002Ftypesense-schema';\n\n   export default defineNuxtModule({\n     meta: { name: 'typesense-sync' },\n     setup(_options, nuxt) {\n       const key = process.env.TYPESENSE_ADMIN_KEY;\n       \u002F\u002F Pas de clé, c’est un build local, pas un échec : on saute plutôt que\n       \u002F\u002F de le casser.\n       if (!key) return;\n\n       nuxt.hook('duxt:search:records', async (records) => {\n         const client = new Client({\n           nodes: [{ url: process.env.TYPESENSE_URL! }],\n           apiKey: key\n         });\n\n         await sync(client, records);\n       });\n     }\n   });\n   ```\n\n   La charge utile est **gelée**. Transformez-la en documents à vous — ne\n   réécrivez jamais un enregistrement et ne triez pas le tableau sur place, car\n   tous les autres auditeurs reçoivent les mêmes objets.\n\n4. **Synchronisez l’ensemble complet, et retirez ce qui a disparu.** Le hook\n   remet l’ensemble *complet* et courant à chaque build : l’ensemble est donc\n   lui-même l’instruction — tout ce que la collection contient et qui n’y figure\n   pas a été supprimé, déplacé ou renommé :\n\n   ```ts [modules\u002Ftypesense.ts]\n   async function sync(client: Client, records: readonly DuxtSearchRecord[]) {\n     const collection = client.collections(docs.name);\n\n     \u002F\u002F Typesense ne crée rien implicitement : importer dans une collection\n     \u002F\u002F qui n’existe pas échoue net, c’est donc le premier build qui la crée.\n     if (!(await collection.exists())) await client.collections().create(docs);\n\n     await collection.documents().import(\n       records.map((record) => ({ ...record })),\n       { action: 'upsert' }\n     );\n\n     \u002F\u002F Tout ce que le build n’a pas remis n’est plus sur le site.\n     const kept = new Set(records.map((record) => record.id));\n     const live = await collection.documents().export();\n\n     const stale = live\n       .split('\\n')\n       .filter(Boolean)\n       .map((line) => JSON.parse(line).id as string)\n       .filter((id) => !kept.has(id));\n\n     \u002F\u002F Supprimez par lots : chaque id entre dans la chaîne du filtre, et un\n     \u002F\u002F seul gros renommage en bâtirait un que Typesense refuse.\n     for (let index = 0; index \u003C stale.length; index += 100) {\n       const batch = stale.slice(index, index + 100).join(',');\n       await collection.documents().delete({ filter_by: `id:[${batch}]` });\n     }\n   }\n   ```\n\n   La collection est créée au premier passage puis laissée telle quelle, et les\n   ids périmés sont supprimés **par lots** — Typesense prend le filtre comme une\n   seule chaîne, et un renommage déplaçant une source entière en bâtirait\n   autrement un qu’il refuse.\n\n   ::callout{type=\"tip\" title=\"Ou échangez plutôt un alias\"}\n   Importez dans une collection nommée d’après le build, pointez un **alias**\n   Typesense dessus, puis jetez la précédente. Chaque build crée sa propre\n   collection : ni la vérification d’existence ni la suppression par lots ne\n   sont nécessaires, et les lecteurs ne voient jamais un index à moitié écrit —\n   au prix d’une réindexation complète à chaque build plutôt que du seul delta.\n   ::\n\n5. **Cherchez depuis le navigateur avec une clé de recherche seule.** La clé\n   d’administration ci-dessus signe les écritures et ne doit jamais atteindre\n   une page. Émettez une clé **restreinte, en lecture de recherche seule** pour\n   le client, et filtrez sur les facettes que le schéma a déclarées :\n\n   ```ts\n   \u002F\u002F `locale` est la langue du CONTENU, pas la langue de l’interface.\n   \u002F\u002F `version` est absente d’une source sans versions : la clause ne s’ajoute\n   \u002F\u002F que s’il y en a une ; figée, elle filtrerait sur `undefined`.\n   const filters = [`locale:${locale}`];\n   if (version) filters.push(`version:${version}`);\n\n   const results = await client.collections('docs').documents().search({\n     q: query,\n     query_by: 'title,content',\n     filter_by: filters.join(' && ')\n   });\n   ```\n\n6. **Vérifiez un build de bout en bout.** Lancez un build avec la clé, et\n   confirmez que la collection contient un enregistrement pour une page dans\n   **chaque** source, version et langue que le site sert — pas seulement la\n   langue par défaut. Le premier build crée la collection ; chacun d’après fait\n   un upsert dans la même.\n\n::\n\n## Ce que les enregistrements règlent déjà pour vous\n\nQuatre propriétés de la charge utile rendent une synchronisation aussi courte\ncorrecte, et toutes les quatre relèvent du\n[contrat du hook](\u002Freference\u002Fhooks), non du conseil de ce guide :\n\n| Propriété | Ce qu’elle apporte à la synchronisation |\n| :--- | :--- |\n| `id` dérive de `url` | Une clé primaire stable : `upsert` suffit, une reconstruction n’est jamais nécessaire |\n| La charge utile est l’ensemble **complet** | Supprimer, c’est comparer à un build, sans exploration ni comptabilité |\n| duxt ne se déclenche pas sur une analyse vide | Un build qui n’a rien analysé ne peut jamais vous dire de vider l’index |\n| L’ordre est déterministe | Deux builds diffèrent exactement là où le site a différé |\n\nUne page qui a écrit `search: false`, et une traduction dans une langue que le\nsite ne route pas, ne produisent aucun enregistrement — donc ni l’une ni l’autre\nn’atteint Typesense.\n\n## En faire un paquet\n\nLe module ci-dessus fait ~40 lignes et appartient à un site. Dès qu’un deuxième\nsite en a besoin, la façon de le partager est **une couche Nuxt**, pas un\nplugin : une couche porte le module, ses valeurs `app.config` par défaut et ses\ncomposants dans un paquet versionné, et un consommateur l’ajoute à côté de duxt.\n\n```ts [nuxt.config.ts]\nexport default defineNuxtConfig({\n  extends: ['@kirchdev\u002Fduxt', 'duxt-typesense']\n});\n```\n\nCette couche possède les informations d’identification, la configuration du\nservice, la politique de synchronisation et l’interface de recherche côté\nnavigateur. duxt n’en gagne aucune —\n[c’est toute la raison de la forme du hook](\u002Freference\u002Fhooks).\n\n## Liste de contrôle\n\n- [ ] Le client est une dépendance de **votre** site, pas de la couche\n- [ ] La clé d’administration vit dans l’environnement de build et n’atteint jamais une page\n- [ ] La collection est créée au premier build et facette `source`, `version` et `locale`\n- [ ] Les enregistrements qui ne sont plus remis sont retirés — par comparaison **par lots** ou par échange d’alias\n- [ ] Un build sans la clé saute la synchronisation au lieu d’échouer\n- [ ] Chaque source, version et langue est représentée dans la collection\n",[2544],"\u002Fguides\u002Fsend-your-pages-to-typesense",{"title":835,"description":838},{"loc":836},"bnvJbu3t2TJsz_CREuRmcUejb1KYnJ3_vCO_DICZ0fI","fr","fr-FR",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2551},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09\"\u002F>\u003Cpath d=\"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z\"\u002F>\u003Cpath d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2553},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"m16.24 7.76l-1.804 5.411a2 2 0 0 1-1.265 1.265L7.76 16.24l1.804-5.411a2 2 0 0 1 1.265-1.265z\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2555},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m8.001-2A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2557},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 5h.01M3 12h.01M3 19h.01M8 5h13M8 12h13M8 19h13\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2559},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Zm-6.8-2.8l2-2m-5-1l2-2m-5-1l2-2m7 11l2-2\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2561},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m14 13l-8.381 8.38a1 1 0 0 1-3.001-3l8.384-8.381M16 16l6-6m-.5.5l-8-8M8 8l6-6M8.5 7.5l8 8\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2563},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2565},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2567},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 5.88L14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88M7 10v12\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2569},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 18.12L10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88M17 14V2\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2571},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.12 2.12 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.12 2.12 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.12 2.12 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.12 2.12 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.12 2.12 0 0 0 1.597-1.16z\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2573},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 8v4m0 4h.01\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2575},"\u003Cpath fill=\"currentColor\" d=\"M20.317 4.37a19.8 19.8 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.3 18.3 0 0 0-5.487 0a13 13 0 0 0-.617-1.25a.08.08 0 0 0-.079-.037A19.7 19.7 0 0 0 3.677 4.37a.1.1 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.08.08 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.08.08 0 0 0 .084-.028a14 14 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13 13 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10 10 0 0 0 .372-.292a.07.07 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.07.07 0 0 1 .078.01q.181.149.373.292a.077.077 0 0 1-.006.127a12.3 12.3 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.08.08 0 0 0 .084.028a19.8 19.8 0 0 0 6.002-3.03a.08.08 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.06.06 0 0 0-.031-.03M8.02 15.33c-1.182 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418m7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2577},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m4-8h2m-2-4h2m2.001 10A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2zM6 13h2M6 9h2\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2579},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 7h10v10M7 17L17 7\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2581,"hidden":1182},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4\"\u002F>\u003Cpath d=\"M14 2v4a2 2 0 0 0 2 2h4M5 12l-3 3l3 3m4 0l3-3l-3-3\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2583},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 16v-4m0-4h.01\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2585},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2587},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 19l-7-7l7-7m7 7H5\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2589},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2591},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",[2593,2594,2595,2596,2597,2598,2599,2600],"\u002Fv0.8.1\u002Fadd-ons\u002Ftypesense","\u002Fv0.7.0\u002Fadd-ons\u002Ftypesense","\u002Fv0.6.0\u002Fadd-ons\u002Ftypesense","\u002Fv0.5.0\u002Fadd-ons\u002Ftypesense","\u002Fv0.4.0\u002Fadd-ons\u002Ftypesense","\u002Fv0.3.4\u002Fadd-ons\u002Ftypesense","\u002Fv0.2.0\u002Fadd-ons\u002Ftypesense","\u002Fv0.1.0\u002Fadd-ons\u002Ftypesense",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2602},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2604},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 8h.01M12 12h.01M14 8h.01M16 12h.01M18 8h.01M6 8h.01M7 16h10m-9-4h.01\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2606},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":943,"top":943,"width":944,"height":944,"rotate":943,"vFlip":945,"hFlip":945,"body":2608},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"pnpm":2610,"npm":2611,"yarn":2612,"bun":2613},"\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">pnpm\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> @kirchdev\u002Fduxt-typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">npm\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> install\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> @kirchdev\u002Fduxt-typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">yarn\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> @kirchdev\u002Fduxt-typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">bun\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> @kirchdev\u002Fduxt-typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"left":943,"top":943,"width":2615,"height":2615,"rotate":943,"vFlip":945,"hFlip":945,"body":2616},32,"\u003Cpath fill=\"#f9ad00\" d=\"M30 10.75h-8.749V2H30Zm-9.626 0h-8.75V2h8.75Zm-9.625 0H2V2h8.749ZM30 20.375h-8.749v-8.75H30Z\"\u002F>\u003Cpath fill=\"#4e4e4e\" d=\"M20.374 20.375h-8.75v-8.75h8.75Zm0 9.625h-8.75v-8.75h8.75ZM30 30h-8.749v-8.75H30Zm-19.251 0H2v-8.75h8.749Z\"\u002F>",{"left":943,"top":943,"width":2615,"height":2615,"rotate":943,"vFlip":945,"hFlip":945,"body":2618},"\u003Cpath fill=\"#f9ad00\" d=\"M30 10.75h-8.749V2H30Zm-9.626 0h-8.75V2h8.75Zm-9.625 0H2V2h8.749ZM30 20.375h-8.749v-8.75H30Z\"\u002F>\u003Cpath fill=\"#fff\" d=\"M20.374 20.375h-8.75v-8.75h8.75Zm0 9.625h-8.75v-8.75h8.75ZM30 30h-8.749v-8.75H30Zm-19.251 0H2v-8.75h8.749Z\"\u002F>",{"left":943,"top":943,"width":2615,"height":2615,"rotate":943,"vFlip":945,"hFlip":945,"body":2620},"\u003Cpath fill=\"#c12127\" d=\"M2 2h28v28H2\"\u002F>\u003Cpath fill=\"#fff\" d=\"M7.25 7.25h17.5v17.5h-3.5v-14H16v14H7.25\"\u002F>",{"left":943,"top":943,"width":2615,"height":2615,"rotate":943,"vFlip":945,"hFlip":945,"body":2622},"\u003Cpath fill=\"#2188b6\" d=\"M28.208 24.409a10.5 10.5 0 0 0-3.959 1.822a23.7 23.7 0 0 1-5.835 2.642a1.63 1.63 0 0 1-.983.55a62 62 0 0 1-6.447.577c-1.163.009-1.876-.3-2.074-.776a1.573 1.573 0 0 1 .866-2.074a4 4 0 0 1-.514-.379c-.171-.171-.352-.514-.406-.388c-.225.55-.343 1.894-.947 2.5c-.83.839-2.4.559-3.328.072c-1.019-.541.072-1.813.072-1.813a.73.73 0 0 1-.992-.343a4.85 4.85 0 0 1-.667-2.949a5.37 5.37 0 0 1 1.749-2.895a9.3 9.3 0 0 1 .658-4.4a10.45 10.45 0 0 1 3.165-3.661S6.628 10.747 7.35 8.817c.469-1.262.658-1.253.812-1.308a3.6 3.6 0 0 0 1.452-.857a5.27 5.27 0 0 1 4.41-1.7S15.2 1.4 16.277 2.09a18.4 18.4 0 0 1 1.533 2.886s1.281-.748 1.425-.469a11.33 11.33 0 0 1 .523 6.132a14 14 0 0 1-2.6 5.411c-.135.225 1.551.938 2.615 3.887c.983 2.7.108 4.96.262 5.212c.027.045.036.063.036.063s1.127.09 3.391-1.308a8.5 8.5 0 0 1 4.277-1.604a1.081 1.081 0 0 1 .469 2.11Z\"\u002F>",{"left":943,"top":943,"width":2615,"height":2615,"rotate":943,"vFlip":945,"hFlip":945,"body":2624},"\u003Cpath fill=\"#fbf0df\" d=\"M29 17c0 5.65-5.82 10.23-13 10.23S3 22.61 3 17c0-3.5 2.24-6.6 5.66-8.44S14.21 4.81 16 4.81s3.32 1.54 7.34 3.71C26.76 10.36 29 13.46 29 17\"\u002F>\u003Cpath fill=\"none\" stroke=\"#000\" d=\"M16 27.65c7.32 0 13.46-4.65 13.46-10.65c0-3.72-2.37-7-5.89-8.85c-1.39-.75-2.46-1.41-3.37-2l-1.13-.69A6.14 6.14 0 0 0 16 4.35a6.9 6.9 0 0 0-3.3 1.23c-.42.24-.86.51-1.32.8c-.87.54-1.83 1.13-3 1.73C4.91 10 2.54 13.24 2.54 17c0 6 6.14 10.65 13.46 10.65Z\"\u002F>\u003Cellipse cx=\"21.65\" cy=\"18.62\" fill=\"#febbd0\" rx=\"2.17\" ry=\"1.28\"\u002F>\u003Cellipse cx=\"10.41\" cy=\"18.62\" fill=\"#febbd0\" rx=\"2.17\" ry=\"1.28\"\u002F>\u003Cpath fill-rule=\"evenodd\" d=\"M11.43 18.11a2 2 0 1 0-2-2.05a2.05 2.05 0 0 0 2 2.05m9.2 0a2 2 0 1 0-2-2.05a2 2 0 0 0 2 2.05\"\u002F>\u003Cpath fill=\"#fff\" fill-rule=\"evenodd\" d=\"M10.79 16.19a.77.77 0 1 0-.76-.77a.76.76 0 0 0 .76.77m9.2 0a.77.77 0 1 0 0-1.53a.77.77 0 0 0 0 1.53\"\u002F>\u003Cpath fill=\"#b71422\" stroke=\"#000\" stroke-width=\".75\" d=\"M18.62 19.67a3.3 3.3 0 0 1-1.09 1.75a2.48 2.48 0 0 1-1.5.69a2.53 2.53 0 0 1-1.5-.69a3.28 3.28 0 0 1-1.08-1.75a.26.26 0 0 1 .29-.3h4.58a.27.27 0 0 1 .3.3Z\"\u002F>\u003Cpath fill=\"#ccbea7\" fill-rule=\"evenodd\" d=\"M14.93 5.75a6.1 6.1 0 0 1-2.09 4.62c-.1.09 0 .27.11.22c1.25-.49 2.94-1.94 2.23-4.88c-.03-.15-.25-.11-.25.04m.85 0a6 6 0 0 1 .57 5c0 .13.12.24.21.13c.83-1 1.54-3.11-.59-5.31c-.1-.11-.27.04-.19.17Zm1-.06a6.1 6.1 0 0 1 2.53 4.38c0 .14.21.17.24 0c.34-1.3.15-3.51-2.66-4.66c-.12-.02-.21.18-.09.27ZM9.94 9.55a6.27 6.27 0 0 0 3.89-3.33c.07-.13.28-.08.25.07c-.64 3-2.79 3.59-4.13 3.51c-.14-.01-.14-.21-.01-.25\"\u002F>",{"pnpm":2626,"npm":2627,"yarn":2628,"bun":2629},"\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">pnpm\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -D\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">npm\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> install\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -D\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">yarn\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -D\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">bun\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> -D\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> typesense\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"left":943,"top":943,"width":2631,"height":2632,"rotate":943,"vFlip":945,"hFlip":945,"body":2633},640,480,"\u003Cpath fill=\"#000091\" d=\"M0 0h213.3v480H0z\"\u002F>\u003Cpath fill=\"#fff\" d=\"M213.3 0h213.4v480H213.3z\"\u002F>\u003Cpath fill=\"#e1000f\" d=\"M426.7 0H640v480H426.7z\"\u002F>",1792683375056]