Astro Migration Plan¶
Status¶
Completed.
This document records how the site was migrated from a traditional static HTML/CSS/JavaScript homepage into an Astro + Tailwind static site. It is kept as project history and as a reference for future maintainers.
Background¶
The original site was a hand-maintained static homepage:
- HTML files at the repository root
- global CSS files
- global browser JavaScript
- assets served directly from
public/or root-level paths - local preview through a small Python server
That approach worked for a small site, but the CSS and JavaScript boundaries became harder to maintain as the homepage grew. Repeated content, bilingual rendering, page-specific behavior, theme switching, search, image galleries, and music playback all started sharing too much global state.
Goals¶
The migration had four goals:
- Preserve the exact current visual design.
- Move the site into a modern static build system.
- Make CSS and JavaScript ownership clearer.
- Keep the final deployed site static and fast.
Non-goals:
- no React/Vue rewrite
- no visual redesign
- no CDN dependency for required assets
- no removal of music or media assets
- no client-side single-page application rewrite
Why Astro¶
Astro was selected because the site is content-heavy and mostly static. It gives the project:
- file-based static routes
- reusable
.astrocomponents - shared layouts
- Vite bundling
- zero required client runtime for ordinary content pages
- static HTML output for GitHub Pages
React and Vue were intentionally not used as the main framework. They are excellent for application-style interfaces, but this personal homepage does not need a large client runtime or app-wide component state. Astro gives enough structure without turning the site into a heavy frontend app.
Why Tailwind¶
Tailwind was introduced to reduce ordinary layout CSS:
- spacing
- grid/flex layout
- alignment
- sizing
- simple responsive rules
- simple typography utilities
Tailwind is not meant to replace every handwritten style. Complex visual systems can remain as local CSS when that is clearer:
- animated theme toggle
- Matrix/canvas backgrounds
- persistent music player
- search overlay
- project gallery and lightbox
- detailed transitions
The long-term rule is: Tailwind for boring layout, local CSS for owned complex components.
Migration Strategy¶
The migration was done in controlled steps:
- Tag the legacy static version.
- Add Astro, Vite, pnpm, and project scripts.
- Move page content into
src/pages/andsrc/components/. - Create
SiteLayout.astrofor shared HTML structure. - Move shared data into
src/data/. - Move runtime scripts into
src/scripts/site/. - Move source CSS into
src/styles/. - Add Tailwind as the utility layer.
- Preserve
public/assets/for audio, images, soundfonts, and local vendor files. - Replace the old local Python server with
pnpm dev. - Switch GitHub Pages deployment to an Astro build workflow.
- Add Playwright smoke tests for critical behavior.
Engineering Principles¶
The migration followed SOLID and DRY principles in a pragmatic frontend form:
- Astro pages became thin route files with one responsibility.
- Shared document structure moved into
SiteLayout.astro. - Repeated page sections moved into components.
- Shared content and translation data moved into
src/data/. - Shared normalization helpers moved into
src/utils/content.ts. - Runtime behavior was split by system under
src/scripts/site/. - Component-specific CSS started moving beside the owning component.
DRY was applied to duplicated content, repeated rendering patterns, and shared helper logic. It was not used to force unrelated visual systems into one abstraction.
The long-term rules are maintained in Engineering Principles.
Resulting Structure¶
src/
components/
data/
layouts/
pages/
scripts/
styles/
public/
assets/
vendor/
specs/
.github/workflows/
Important boundaries:
src/pages/owns routes.src/layouts/SiteLayout.astroowns document structure and script ordering.src/components/owns reusable markup.src/data/owns structured content and metadata.src/scripts/site/owns runtime behavior.src/styles/owns source CSS and Tailwind entrypoints.public/owns served static assets only.
Completed Work¶
- Created the Astro project structure.
- Added pnpm scripts for development, build, preview, type checking, and e2e tests.
- Migrated static pages into Astro routes.
- Preserved the existing visual design.
- Localized required frontend assets.
- Kept music assets and soundfont assets under
public/assets/. - Moved source JavaScript from public/static paths into
src/scripts/site/. - Moved source CSS into
src/styles/and component-owned CSS directories. - Added Tailwind build support.
- Removed the old Python server entrypoint.
- Added GitHub Actions deployment for GitHub Pages.
- Added Playwright smoke tests.
- Added project maintenance specs.
Validation¶
The expected validation commands are:
The smoke test suite should confirm:
- homepage renders
- language switch works
- theme switch works
- core routes render their headings
- music page binds the persistent player
- critical pages do not emit browser console errors
Git Tags¶
Historical tags were used to preserve important states:
legacy-static-html-2026-07-06: original static HTML/CSS/JS site before Astro migrationastro-migration-2026-07-06: Astro migration milestonepre-css-refactor-2026-07-06: checkpoint before deeper CSS cleanup
These tags should not be deleted. They document the architectural transition.
Deployment Model¶
Deployment should use GitHub Actions:
- install dependencies with pnpm
- build the site with Astro
- upload
dist/ - deploy to GitHub Pages
The site should not rely on GitHub Pages Jekyll processing.
Future Rules¶
Future work should continue from the Astro structure, not from the old static HTML model.
Do not reintroduce:
- root-level source HTML as the primary editing surface
- source CSS or JavaScript under
public/ - CDN dependencies for required runtime assets
- large unowned global CSS files
- a Python server as the normal development workflow
When extending the site, use the ownership rules in specs/maintenance-plan.md.