Appearance
📁 Architecture des Fichiers
Structure Complète du Projet
/
├── public/ # Assets statiques servis tels quels
│ ├── locales/ # Fichiers de traduction JSON
│ │ ├── en/
│ │ │ ├── common.json # Traductions communes (theme, locale, keyboard)
│ │ │ ├── components.json # Traductions des composants
│ │ │ └── sections.json # Traductions des sections
│ │ └── fr/ # Même structure pour le français
│ ├── themes/
│ │ └── themes.css # Définition des CSS variables pour les thèmes
│ ├── tracking.json # Configuration Matomo (non versionné)
│ ├── avatar_254.webp # Photo de profil 256x256
│ └── avatar_128.webp # Photo de profil 128x128
│
├── src/
│ ├── components/ # Composants Astro réutilisables
│ │ ├── sections/ # Sections principales du CV
│ │ │ ├── About.astro # Section "À propos"
│ │ │ ├── Hero.astro # Hero avec photo et contacts
│ │ │ ├── Experience.astro # Expériences professionnelles
│ │ │ ├── Projects.astro # Exemples de projets
│ │ │ ├── Skills.astro # Compétences techniques
│ │ │ ├── Education.astro # Formation et certificats
│ │ │ └── Tail.astro # Footer avec profil GitHub
│ │ ├── Dialog.astro # Modale mentions légales
│ │ ├── Section.astro # Wrapper de section avec titre
│ │ ├── ThemeSwitch.astro # Sélecteur de thème
│ │ ├── LocaleSwitch.astro # Sélecteur de langue
│ │ └── KeyboardManager.astro # Gestion palette de commandes
│ │
│ ├── icons/ # Icônes SVG (23 fichiers)
│ │ ├── html.astro, css.astro, javascript.astro, ...
│ │ ├── GitHub.astro, LinkedIn.astro, Phone.astro, Mail.astro
│ │ ├── FlagFr.astro, FlagEn.astro
│ │ └── themeSwitch.astro, WorldMap.astro, Arrow.astro
│ │
│ ├── layouts/
│ │ └── Layout.astro # Layout principal avec <head>, SEO, etc.
│ │
│ ├── pages/ # Routes du site
│ │ ├── index.astro # Redirection vers /fr/ ou /en/
│ │ ├── fr/
│ │ │ └── index.astro # Page française
│ │ └── en/
│ │ └── index.astro # Page anglaise
│ │
│ ├── utils/ # Fonctions utilitaires
│ │ ├── i18n.ts # Système de traduction custom
│ │ ├── theme.ts # Gestion des thèmes
│ │ ├── locale.ts # Gestion du changement de langue
│ │ └── tracking.ts # Chargement Matomo
│ │
│ ├── constants/
│ │ └── social-icons-svg.ts # Icônes SVG en format string
│ │
│ ├── types.d.ts # Types TypeScript custom
│ ├── cv.d.ts # Types pour le format JSON Resume
│ ├── global.d.ts # Déclarations globales Alpine.js
│ └── env.d.ts # Types d'environnement Astro
│
├── documentation/ # Documentation technique modulaire
│ ├── README.md # Index général
│ ├── 01-stack-technique.md
│ ├── 02-architecture.md
│ └── ...
│
├── cv-fr.json # Données du CV en français
├── cv-en.json # Données du CV en anglais
├── mentions-fr.json # Mentions légales FR
├── mentions-en.json # Mentions légales EN
│
├── astro.config.mjs # Configuration Astro
├── tailwind.config.mjs # Configuration Tailwind
├── tsconfig.json # Configuration TypeScript
└── package.json # Dépendances et scriptsDétails des Répertoires
/public/
Assets statiques copiés tels quels dans /dist/ au build
Pourquoi public/ et pas src/ ?
- Les fichiers dans
public/sont servis tels quels sans transformation - Les traductions JSON doivent être fetchées dynamiquement (format original)
- Les thèmes CSS sont chargés de manière asynchrone
- Les images sont référencées directement par URL
Contenu :
locales/- Traductions i18n (6 fichiers JSON)themes/themes.css- CSS variables pour light/dark modeavatar_*.webp- Photos de profil optimiséestracking.json- Config Matomo (non versionné, ajouté en.gitignore)
/src/components/
Composants Astro réutilisables
/src/components/sections/
Les sections principales du CV, dans l'ordre d'affichage :
- Hero.astro - En-tête avec photo, nom, contacts
- About.astro - Section "À propos" avec résumé
- Experience.astro - Expériences professionnelles avec expand/collapse
- Projects.astro - Projets remarquables
- Skills.astro - Compétences techniques avec tooltips
- Education.astro - Formation et certifications
- Tail.astro - Footer avec lien GitHub
Convention : Chaque section reçoit locale et les données du CV correspondantes.
Composants utilitaires
- Section.astro - Wrapper générique pour sections avec titre h2
- Dialog.astro - Modale mentions légales (Alpine.js)
- ThemeSwitch.astro - Select pour choisir light/dark/system
- LocaleSwitch.astro - Select pour choisir FR/EN
- KeyboardManager.astro - Palette de commandes (HotKeyPad)
/src/icons/
Composants SVG Astro (23 fichiers)
Technologies :
- html.astro, css.astro, javascript.astro, typescript.astro, react.astro, vue.astro, nodejs.astro, php.astro, symfony.astro, mysql.astro, docker.astro, figma.astro, vscode.astro
Social/Contact :
- GitHub.astro, LinkedIn.astro, X.astro, Phone.astro, Mail.astro
UI :
- FlagFr.astro, FlagEn.astro, themeSwitch.astro, WorldMap.astro, Arrow.astro
Usage :
astro
---
import Html from "@/icons/html.astro";
---
<Html /> <!-- Injecte le SVG inline -->Note : Pour HotKeyPad, j'utilise /src/constants/social-icons-svg.ts car HotKeyPad nécessite des strings HTML, pas des composants.
/src/layouts/
Layout principal du site
Layout.astro - Wrapper de toutes les pages :
<head>avec SEO (title, meta, Open Graph, Twitter Cards)- Import des thèmes CSS
- Script Matomo
<slot />pour le contenu de la page
Props :
typescript
interface Props {
title: string; // "Simon Chabrier - Développeur Full Stack"
image: string; // Chemin vers avatar
summary: string; // Meta description
theme: string; // Thème par défaut
locale: "fr" | "en";
}/src/pages/
Routes du site (système de routing Astro)
/src/pages/index.astro
Page racine qui redirige vers /fr/ ou /en/
Logique de redirection :
- Vérifie
localStorage.getItem("locale") - Si existe → Redirige vers
/[locale]/ - Sinon → Détecte langue navigateur (
navigator.language) - Fallback →
/fr/
/src/pages/fr/index.astro et /src/pages/en/index.astro
Pages principales (identiques, sauf locale et imports)
Structure :
astro
---
import * as cv from "@cv-fr"; // ou @cv-en
import * as legal from "@mentions-fr"; // ou @mentions-en
import Layout from "@/layouts/Layout.astro";
import Hero from "@/components/sections/Hero.astro";
// ... autres imports
const { basics, work, education, skills, projects } = cv;
---
<Layout title={basics.name} locale="fr" ...>
<main>
<Hero basics={basics} locale="fr" />
<About about={basics.summary} locale="fr" />
<Experience work={work} locale="fr" />
<!-- ... autres sections -->
</main>
</Layout>/src/utils/
Fonctions utilitaires TypeScript
- i18n.ts - Système de traduction custom (fonction
t()) - theme.ts - Gestion des thèmes (initializeTheme, updateTheme, etc.)
- locale.ts - Changement de langue (switchLocale, getStoredLocale)
- tracking.ts - Chargement Matomo analytics
Voir Utilitaires pour la documentation complète.
/src/constants/
Constantes partagées
social-icons-svg.ts - Icônes SVG en format string :
typescript
export const SOCIAL_ICONS_SVG = {
GitHub: `<svg ...>...</svg>`,
LinkedIn: `<svg ...>...</svg>`,
X: `<svg ...>...</svg>`
} as const;Raison : HotKeyPad nécessite des strings HTML, pas des composants Astro.
Types TypeScript
src/cv.d.ts
Types pour le format JSON Resume :
typescript
export interface Basics {
name: string;
label: string;
image: string;
email: string;
phone: string;
profiles: Profiles[];
location: Location;
}
export interface Work {
name: string;
position: string;
startDate: string;
endDate: string | null;
summary: string | string[];
responsibilities?: string[];
achievements?: string[];
skills?: string[];
// ...
}
// ... autres typessrc/global.d.ts
Déclarations Alpine.js pour TypeScript :
typescript
declare global {
interface Window {
Alpine: import('alpinejs').Alpine;
}
}src/env.d.ts
Types environnement Astro (généré automatiquement).
Fichiers à la Racine
Données
- cv-fr.json / cv-en.json - Données du CV au format JSON Resume
- mentions-fr.json / mentions-en.json - Mentions légales
Configuration
- astro.config.mjs - Config Astro (site, base, i18n, integrations)
- tailwind.config.mjs - Config Tailwind (couleurs custom, plugins)
- tsconfig.json - Config TypeScript (path aliases, moduleResolution)
- package.json - Dépendances et scripts npm
Conventions de Nommage
Fichiers
- Composants : PascalCase (
Hero.astro,ThemeSwitch.astro) - Utilitaires : camelCase (
i18n.ts,theme.ts) - Icônes : PascalCase (
GitHub.astro,html.astro) - Types :
.d.tsextension
Imports
J'utilise les path aliases pour des imports propres :
typescript
import { t } from "@/utils/i18n"; // au lieu de ../../utils/i18n
import * as cv from "@cv-fr"; // au lieu de ../../cv-fr.json
import Hero from "@/components/sections/Hero.astro";Outputs (après build)
Après pnpm build, le répertoire /dist/ contient :
dist/
├── _astro/ # Assets optimisés (CSS, JS avec hash)
├── en/
│ └── index.html # Page anglaise compilée
├── fr/
│ └── index.html # Page française compilée
├── index.html # Redirection
├── locales/ # Traductions copiées
├── themes/ # CSS copiés
├── avatar_*.webp # Images copiées
└── ...