Bilingual (EN/FR) portfolio website showcasing engineering and research projects
in deep learning, signal processing, embedded systems and web development.
- Bilingual — Full English/French support with locale-prefixed routing and language switcher
- Dark / Light mode — Class-based theming with system preference detection
- Project showcase — Grid and timeline views with tag-based filtering
- Rich markdown — LaTeX equations (KaTeX), syntax highlighting (Shiki), video embedding, figure captions
- Project detail pages — Table of contents, reading progress bar, image lightbox, appendices with bibliography and downloadable documents
- Animations — Scroll-triggered animations and typewriter effect via framer-motion, with
prefers-reduced-motionsupport - Optimized images — Sharp-based image processing at build time with automatic WebP conversion and fallback for oversized images
- RSS feed — Auto-generated project feed
| Category | Technologies |
|---|---|
| Framework | Astro 5, React 19 |
| Language | TypeScript |
| Styling | Tailwind CSS 3.4, CSS custom properties |
| Content | Markdown / MDX, Zod schema validation |
| Math | remark-math, rehype-katex |
| Animations | framer-motion, CSS animations |
| Icons | lucide-react |
| Images | Sharp |
| Deployment | GitHub Pages, GitHub Actions |
- Node.js 20+
- npm
git clone https://github.com/AstyanM/portfolio.git
cd portfolio
npm installnpm run dev # Start dev server
npm run build # Build for production
npm run preview # Preview production buildsrc/
├── assets/images/projects/ # Project images (optimized at build)
├── components/
│ ├── astro/ # Server-rendered components
│ └── react/ # Interactive client components
├── content/
│ ├── config.ts # Zod content schemas
│ └── projects/{en,fr}/ # Bilingual project markdown files
├── i18n/
│ ├── ui.ts # Translation strings (60+ keys)
│ └── utils.ts # i18n helper functions
├── layouts/
│ ├── BaseLayout.astro # Main layout (ViewTransitions)
│ └── ProjectLayout.astro # Project detail layout
├── pages/
│ ├── en/ # English routes
│ ├── fr/ # French routes
│ ├── index.astro # Root redirect
│ ├── 404.astro # Error page
│ └── rss.xml.ts # RSS feed
├── plugins/ # Custom rehype plugins
├── services/ # Custom Astro services (image-service.mjs)
├── styles/global.css # Theme variables & prose styles
└── consts.ts # Available tags
- Create a markdown file in both
src/content/projects/fr/andsrc/content/projects/en/with the same filename - Add frontmatter:
---
title: "Project Title" # required
lang: en # en | fr
description: "Full project summary"
cardDescription: "Short one-liner for project cards"
date: "2024-06-15"
year: 2024
tags: ["Deep Learning", "Web"] # from src/consts.ts
cover: "./cover.jpg"
teamSize: 3
liveUrl: https://example.com
repoUrl: https://github.com/...
repoPrivate: false
draft: false
conclusion: "Closing remarks displayed in a separate section."
impact:
- value: "95%"
label: "Accuracy"
appendix:
sources:
- authors: "Doe, J."
year: 2023
title: "Paper Title"
publisher: "Journal"
url: https://...
documents:
- title: "Report"
url: "/docs/report.pdf"
type: pdf
---- Place images in
src/assets/images/projects/{slug}/ - Reference images in markdown with relative paths:
— Astro will optimize them to WebP automatically - For SVGs or videos, place them in
public/images/projects/{slug}/and use absolute paths instead
The site deploys automatically to GitHub Pages on push to main via .github/workflows/deploy.yml.
// astro.config.mjs
site: 'https://astyanm.github.io'
base: '/portfolio/'Astyan Martin — Engineering student