2 Architecture
Ella Mizuki edited this page 2026-07-03 04:33:23 +00:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Architecture

beta-website — A multilingual Astro 7.x personal website with content collections, i18n routing, and code-first TypeScript dictionaries.

Tech Stack

Layer Technology Version
Framework Astro 7.0.6
Language TypeScript 6.0.3
Styling Tailwind CSS 4.3.2 (Vite plugin)
Content Astro Content Collections Built-in
i18n Custom (TypeScript dictionaries) —
Syntax Highlighting Shiki Built-in (astro)
Deployment Static (Vercel) vercel.json
Package Manager pnpm 11.8.0
Runtime Node.js 24.x

Project Structure

beta-website/
├── astro.config.ts                 # Astro config + i18n, fonts, markdown, Vite/Tailwind
├── src/
│   ├── content.config.ts           # Content collections: blog, snippets, projects
│   ├── content/                    # MDX content (per-locale)
│   │   ├── blog/                   # Blog posts (6 locales each)
│   │   ├── snippets/               # Code snippets / technical notes (6 locales)
│   │   └── projects/               # Project entries (6 locales)
│   ├── i18n/
│   │   ├── config.ts               # Locale list, metadata, helpers
│   │   ├── types.ts                # Dictionary type (strict, Discriminated Unions)
│   │   ├── index.ts                # Dictionary registry + getDictionary()
│   │   └── locales/                # 6 locale dictionaries (en, pt-br, ja, zh-cn, de, fr)
│   ├── lib/
│   │   ├── routes.ts               # Locale-aware path helpers
│   │   ├── content.ts              # Collection queries + fallback logic
│   │   ├── content-utils.ts        # ID parsing, reading time (CJK-aware)
│   │   ├── code-blocks.ts          # Shiki language labels
│   │   └── project-utils.ts        # Taxonomy helpers
│   ├── components/
│   │   ├── pages/                  # Page-level components (HomePage, BlogPostPage, etc.)
│   │   ├── LanguageSwitcher.astro  # Locale picker with fallback UI
│   │   ├── SiteHeader.astro        # Nav + locale switcher
│   │   ├── SiteFooter.astro
│   │   ├── Prose.astro             # Prose typography (h2–h6, code, tables)
│   │   ├── CodeBlockTools.astro    # Copy button + language label (client script)
│   │   ├── TableOfContents.astro
│   │   └── ... (SeoHead, Tag, LogoMark, etc.)
│   ├── layouts/
│   │   └── BaseLayout.astro        # HTML shell, fonts, SEO, header/footer
│   ├── pages/
│   │   ├── index.astro             # / (EN default)
│   │   ├── [section]/index.astro          # /blog/, /snippets/, etc. (EN)
│   │   ├── [locale]/index.astro    # /{locale}/ (5 non-default locales)
│   │   ├── [locale]/[section]/index.astro  # /{locale}/blog/, /snippets/, etc.
│   │   ├── blog/[slug].astro       # /blog/:slug (EN)
│   │   ├── [locale]/blog/[slug].astro      # /{locale}/blog/:slug
│   │   ├── snippets/[slug].astro   # /snippets/:slug (EN)
│   │   ├── [locale]/snippets/[slug].astro  # /{locale}/snippets/:slug
│   │   ├── projects/[slug].astro   # /projects/:slug (EN)
│   │   └── [locale]/projects/[slug].astro  # /{locale}/projects/:slug
│   └── styles/
│       └── global.css              # Tailwind v4 + CSS custom properties
├── scripts/
│   ├── translate-content.ts        # CLI: generate missing translations via adapter
│   ├── check-content.ts            # Validate content structure across locales
│   ├── migrate-legacy-content.ts   # One-time migration from legacy format
│   ├── new-post.ts                 # Scaffold new blog post
│   └── new-snippet.ts              # Scaffold new snippet
└── dist/                           # Static build output

Page Generation Strategy

Static Routes (getStaticPaths)

Route Paths Generated
/ EN only (index.astro)
/{section}/ EN section indexes (blog, snippets, projects, about, contact)
/{locale}/ 5 non-default locales
/{locale}/{section}/ 5 locales × 5 sections (blog, snippets, projects, about, contact)
/blog/[slug] EN entries only
/{locale}/blog/[slug] All published entries per locale (with fallback)
/snippets/[slug] EN entries only
/{locale}/snippets/[slug] All published per locale
/projects/[slug] EN entries only
/{locale}/projects/[slug] All published per locale

Note: Non-default locale pages use getLocalizedListing() → automatic EN fallback when translation missing.

Styling System

Tailwind CSS v4 (via @tailwindcss/vite)

  • No config file — uses CSS-first config in global.css
  • Custom properties for colors, spacing, radii, fonts
  • Dark-mode only (color-scheme: dark on <html>)

Fonts (Astro Assets + Fontsource)

Variable Font Weights Source
--font-inter Inter 100–900 Fontsource (local WOFF2)
--font-jetbrains-mono JetBrains Mono 100–800 variable Fontsource (local WOFF2)

Preloaded via <Font cssVariable="--font-inter" preload /> in BaseLayout.astro.

Prose Typography (Prose.astro)

Scoped .prose styles for MDX content:

  • h2–h6 with scroll-margin, custom sizes/colors
  • h4 — muted color, smaller
  • h5/h6 — JetBrains Mono, uppercase, letter-spaced
  • Code blocks enhanced by CodeBlockTools.astro (client-side copy button)
  • Tables, blockquotes, HR, lists styled

Client-Side Interactivity

Component Purpose Hydration
CodeBlockTools.astro Copy code button, language label <script> + astro:page-load
LanguageSwitcher.astro <details> dropdown (CSS-only) None (pure HTML/CSS)
TableOfContents.astro Client-side scroll spy <script> (IntersectionObserver)
ShimmerText.astro Animated gradient text CSS animation
ClientRouter View transitions (Astro) Built-in

Performance Notes

  • Static generation — all pages pre-rendered at build
  • Zero JS by default — only interactive components hydrate
  • Fonts self-hosted — WOFF2 via Fontsource, preloaded
  • CSS custom properties — no runtime theme switching overhead
  • View Transitions — ClientRouter for SPA-like navigation
  • Image optimization — Astro Assets (if used in content)