Yu Wu Hsien - Profile Picture
YU WU HSIEN

Just simple folk, with HTML, trying to make a living.

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

A personal blog built with VitePress 2.0-alpha and Tailwind CSS v4. The site uses a fully custom theme with Vue 3 components, featuring a responsive layout with three distinct page types.

Site URL: https://ywh.sh

Architecture

Project Structure

.
├── .vitepress/
│   ├── cache/              # Build cache (git-ignored)
│   ├── dist/               # Production build output (git-ignored)
│   ├── theme/
│   │   ├── index.ts        # Theme entry point
│   │   ├── Layout.vue      # Main layout (conditional rendering)
│   │   ├── Header.vue      # Profile image + site title
│   │   ├── Footer.vue      # Copyright + email link
│   │   ├── Aside.vue       # Navigation sidebar
│   │   ├── Article.vue     # Blog post view
│   │   ├── Writing.vue     # Post list (grouped by year)
│   │   ├── Page.vue        # Static page view
│   │   ├── Pattern.vue     # Decorative background SVG
│   │   ├── posts.data.ts   # Content loader for blog posts
│   │   └── style.css       # Tailwind imports + custom styles
│   └── config.ts           # VitePress + Tailwind config
├── writing/                # Blog posts directory
│   ├── *.md                # English blog posts
│   └── tw/                 # Traditional Chinese translations
├── index.md                # Home page (frontmatter: home: true)
├── writing.md              # Writing list page (frontmatter: page: true)
└── package.json

Page Types

The theme conditionally renders three different views based on frontmatter:

Page TypeFrontmatterComponentDescription
Homehome: truePage.vueIntroduction/about page
Writing Listpage: trueWriting.vueBlog posts grouped by year
Article(default)Article.vueIndividual blog post

Theme Components

  • Layout.vue: Main wrapper using flex layout, conditionally renders Page/Writing/Article based on frontmatter
  • Header.vue: Gravatar profile image, site title, tagline with responsive grid
  • Footer.vue: Copyright notice with email link
  • Aside.vue: Navigation sidebar with active state detection (About, Writing links)
  • Article.vue: Blog post renderer with prose styling and date display
  • Writing.vue: Post list view, groups posts by year (newest first)
  • Page.vue: Simple content wrapper for static pages
  • Pattern.vue: Decorative gradient SVG background pattern

Content Loading

posts.data.ts uses VitePress createContentLoader() to:

  • Scan writing/*.md files
  • Extract title, URL, date, excerpt from frontmatter
  • Sort posts by date (newest first)

Key Integration Points

  • Tailwind Integration: Via @tailwindcss/vite plugin in .vitepress/config.ts
  • Theme Registration: .vitepress/theme/index.ts exports custom Layout
  • Runtime API: Components use useData() for site data and useRoute() for navigation
  • Content Rendering: Uses VitePress <Content /> component in Article.vue and Page.vue

Development Commands

bash
npm run blog:dev      # Start dev server with hot reload
npm run blog:build    # Build for production
npm run blog:preview  # Preview production build

Technology Stack

  • VitePress: v2.0.0-alpha.12
  • Tailwind CSS: v4.1.15 (with @tailwindcss/typography)
  • Vue 3: Provided by VitePress
  • TypeScript: For config and components

Development Notes

Adding Blog Posts

  1. Create a new .md file in writing/ directory
  2. Add frontmatter:
    yaml
    ---
    title: "Post Title"
    description: "SEO description"
    date: 2025-01-14
    head:
      - - link
        - rel: canonical
          href: "https://ywh.sh/writing/post-slug"
    ---
  3. Posts are automatically sorted by date in the writing list

Styling

  • Primary Color: Emerald (emerald-500/600 for links and accents)
  • Font: Inter (imported from fonts.bunny.net)
  • Typography: Tailwind prose plugin with custom color overrides
  • Responsive: Mobile-first with md: breakpoints

SEO Configuration

The config includes:

  • Canonical URLs for each page
  • Open Graph meta tags (og:type, og:url, og:title, og:image)
  • Twitter card support (@takeshiyu_hey)
  • Sitemap generation for https://ywh.sh

Tailwind CSS v4

  • Imported via @import "tailwindcss" in style.css
  • Uses @source directive to scan all Vue/TS files
  • Custom prose color overrides for links, headings, code blocks