Solution Starlight - Symlinks avec docsLoader()
Solution Starlight - Symlinks avec docsLoader()
Documentation technique
DOC : Analyse du problème1/4
Problème initial :
- Sync script complexe qui cassait la structure
- Duplication des fichiers entre
docs/,GettingStarted/etapps/web/src/content/docs/ - Starlight échouait à afficher les docs
DOC : Analyse du problème2/4
Contrainte :
- Starlight nécessite son propre
docsLoader()pour fonctionner correctement - GettingStarted doit être disponible sur GitHub Actions pour le déploiement
- Repo privé (pas public internet) mais GettingStarted ignoré pour éviter de “saturer” le repo
DOC : Analyse du problème3/4
Documentation officielle :
- Starlight
docsLoader()charge les fichiers depuissrc/content/docs/ - Starlight sidebar autogenerate s’attend à ce que les chemins commencent par
src/content/docs/ glob()avec unbaseexterne produit des chemins qui ne commencent pas par ce préfixe- L’utilisation de
glob()au lieu dedocsLoader()cause l’erreur “Entry docs → docs was not found”
DOC : Analyse du problème4/4
Résultat de recherche GitHub :
“Root cause: Starlight’s bundled docsLoader() — and its autogenerate sidebar logic — hardcode the docs location as src/content/docs/. Specifically, getRoutePathRelativeToCollectionRoot in utils/navigation.ts strips that prefix from entry.filePath before matching against the autogenerate directory argument. Our bare glob({ base: ‘../docs’ }) loader served content pages just fine but left every entry.filePath rooted at ../docs/…, so the prefix-strip never fired and the autogenerate filter returned zero matches.”
SPEC : Solution implémentée - Symlinks + docsLoader()1/3
Décision :
- Revenir à
docsLoader()(requis par Starlight) - GettingStarted ne sera plus ignoré par git
- Symlinks pour docs/ et GettingStarted/
- Pas de script de sync nécessaire
- NE PAS utiliser
preserveSymlinks: truedans Vite (cause une erreur de module ‘piccolore’)
SPEC : Solution implémentée - Symlinks + docsLoader()2/3
Avantages :
- ✅ Pas de duplication de fichiers
- ✅ Pas de script de sync complexe
- ✅ Starlight fonctionne avec son
docsLoader()natif - ✅ Édition directe dans les répertoires racine
- ✅ Maintenable et simple
- ✅ Disponible sur GitHub Actions (GettingStarted commité)
SPEC : Solution implémentée - Symlinks + docsLoader()3/3
Inconvénients :
- ❌ GettingStarted commité (peut “saturer” le repo)
- ❌ Symlinks peuvent poser des problèmes sur Windows (mais GitHub Actions/Linux ok)
CODE : Modifications effectuées
1. Modification .gitignore
Retiré :
# Initial setup/GettingStartedGettingStarted est maintenant commité sur git.
2. Configuration src/content.config.ts
Retour à docsLoader() :
import { defineCollection } from 'astro:content';import { glob } from 'astro/loaders';import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders';import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';import { z } from 'astro/zod';
const blog = defineCollection({ loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }), schema: ({ image }) => z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), heroImage: z.optional(image()), }),});
const docs = defineCollection({ loader: docsLoader(), schema: docsSchema(),});
export const collections = { blog, docs, i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }),};Note : Le champ visibility custom a été retiré car non nécessaire pour le moment.
3. Création des symlinks1/2
cd apps/web/src/content/docsln -s ../../../docs docsln -s ../../../GettingStarted getting-startedNote importante sur les chemins :
- Les symlinks doivent utiliser
../../../(3 niveaux) carapps/web/src/content/docs/est à 3 niveaux de profondeur depuis la racine - Structure résultante :
3. Création des symlinks2/2
apps/web/src/content/docs/├── 404.md├── docs -> ../../../docs└── getting-started -> ../../../GettingStarted4. Configuration Starlight
Sidebar avec directory :
sidebar: [ { label: 'Getting Started', items: [{ autogenerate: { directory: 'getting-started' } }], }, { label: 'Documentation Technique', items: [{ autogenerate: { directory: 'docs' } }], },],5. Configuration Vite
NE PAS utiliser preserveSymlinks :
vite: { plugins: [ tailwindcss(), ], // PAS de preserveSymlinks: true - cause une erreur "Cannot find module 'piccolore'" optimizeDeps: { exclude: ['@sanity/client', '@sanity/astro'], }, server: { fs: { allow: ['../../node_modules', '.'], }, watch: { ignored: ['**/sanity.types.ts', '**/schema.json'], }, }, ssr: { noExternal: ['@sanity/preview-url-secret', '@sanity/client', '@sanity/astro', '@sanity/visual-editing', '@sanity/visual-editing/react'], },},6. Workflow GitHub Actions
Sync-docs.sh retiré :
- L’étape de sync a été supprimée de
.github/workflows/deploy-dev.yml - Les symlinks sont gérés par git et fonctionnent sur GitHub Actions
TEST : Validation
- ✅ Typecheck réussi (0 erreurs, 0 warnings)
- ✅ Build réussi
- ⚠️ Pagefind indexation (1 fichier HTML) - à vérifier dans le dev server
- ✅ Sitemap généré
INTÉG : Documentation et notes
Workflow de développement local :
- Édition : Éditer directement dans
docs/etGettingStarted/à la racine - Accès : Starlight lit les fichiers via symlinks et docsLoader()
- Commit : Committer GettingStarted quand il y a des changements significatifs
Notes importantes :
- Symlinks sur Windows : Peuvent poser des problèmes si vous développez sur Windows. Git sur Windows suit les symlinks par défaut mais ils nécessitent des permissions d’administrateur.
- GitHub Actions : Les symlinks fonctionnent correctement sur Linux (GitHub Actions)
- preserveSymlinks : NE PAS utiliser
preserveSymlinks: truedans la config Vite - cela cause une erreur “Cannot find module ‘piccolore’” lors du typecheck/build - docsLoader() : Starlight exige
docsLoader()pour sa collectiondocs-glob()ne fonctionne pas avec Starlight sidebar autogenerate
Actions recommandées :
- Tester le dev server : Lancer
task devet vérifier l’accès aux docs - Vérifier Pagefind : Confirmer que les docs sont bien indexés pour la recherche
- Test sur Windows : Si vous utilisez Windows, vérifier que les symlinks fonctionnent correctement
Conclusion
Cette solution utilise docsLoader() (requis par Starlight) combiné avec des symlinks pour permettre l’édition dans les répertoires racine. Les docs sont maintenant gérés comme une source unique de vérité dans leurs répertoires originaux, avec GettingStarted commité pour le déploiement.