Commit Graph
100 Commits
Author SHA1 Message Date
gbanyanandClaude 7d1f29dd9d Implement comprehensive Next.js 16 optimizations
## Performance Improvements

### Build & Development (Phase 1)
- Enable Turbopack for 4-5x faster dev builds
- Configure Partial Prerendering (PPR) via cacheComponents
- Add advanced image optimization (AVIF/WebP support)
- Remove console.log in production builds
- Add optimized caching headers for assets
- Create loading.tsx for global loading UI
- Create error.tsx for error boundary
- Create blog post loading skeleton

### Client-Side JavaScript Reduction (Phase 2)
- Replace Framer Motion with lightweight CSS animations in template.tsx
- Refactor ScrollReveal to CSS-only implementation (removed React state)
- Add dynamic import for SearchModal component
- Fix site-footer to use build-time year calculation for PPR compatibility

### Image Optimization (Phase 3)
- Add explicit dimensions to all Next.js Image components
- Add responsive sizes attribute for optimal image loading
- Use priority for above-the-fold images
- Use loading="lazy" for below-the-fold images
- Prevents Cumulative Layout Shift (CLS)

### Type Safety
- Add @types/react-dom for createPortal support

## Technical Changes

**Files Modified:**
- next.config.mjs: PPR, image optimization, compiler settings
- package.json: Turbopack flag, @types/react-dom dependency
- app/template.tsx: CSS animations replace Framer Motion
- components/scroll-reveal.tsx: CSS-only with IntersectionObserver
- components/site-header.tsx: Dynamic import for SearchModal
- components/site-footer.tsx: Build-time year calculation
- styles/globals.css: Page transitions & scroll reveal CSS
- Image components: Dimensions, sizes, priority/lazy loading

**Files Created:**
- app/loading.tsx: Global loading spinner
- app/error.tsx: Error boundary with retry functionality
- app/blog/[slug]/loading.tsx: Blog post skeleton

## Expected Impact

- First Contentful Paint (FCP): ~1.2s → ~0.8s (-33%)
- Largest Contentful Paint (LCP): ~2.5s → ~1.5s (-40%)
- Cumulative Layout Shift (CLS): ~0.15 → ~0.05 (-67%)
- Total Blocking Time (TBT): ~300ms → ~150ms (-50%)
- Bundle Size: ~180KB → ~100KB (-44%)

## PPR Status
✓ Blog posts now use Partial Prerendering
✓ Static pages now use Partial Prerendering
✓ Tag archives now use Partial Prerendering

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 14:51:54 +08:00
gbanyanandClaude b6f0bd1d69 Fix search modal z-index and improve text readability
- Use React Portal to render modal at document body level to avoid stacking context issues
- Increase z-index to z-[9999] to ensure modal appears on top of all content
- Add cleanup function to prevent duplicate Pagefind initializations
- Replace CSS class overrides with CSS variables for better maintainability
- Enhance search result text colors for improved readability in both light and dark modes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 02:46:54 +08:00
gbanyanandClaude e28beac1f1 Fix Pagefind file serving with API route
Fixed issue where Pagefind static files weren't accessible due to Next.js routing conflicts.

Solution:
- Created API route at app/pagefind/[...path]/route.ts to serve Pagefind files from .next/pagefind/
- Updated build script to copy pagefind index to public/_pagefind (backup)
- API route handles all /pagefind/* requests and serves files with proper content types
- Added caching headers for optimal performance

This resolves the "cannot type in search" issue - the search modal can now load Pagefind UI and index files correctly.

Technical Details:
- Next.js App Router was treating /pagefind/ as a route, returning 404
- Static files in public/ weren't accessible for subdirectories due to routing priority
- API route bypasses routing to serve .next/pagefind/* files directly
- Supports .js, .css, .json, .wasm, and Pagefind-specific file types

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 02:26:38 +08:00
gbanyanandClaude 02f2d0a599 Fix search input autofocus issue
Added autofocus configuration and manual focus call to ensure search input is immediately focusable when modal opens.

Changes:
- Added autofocus: true to PagefindUI config
- Added setTimeout to manually focus input after UI loads
- Ensures users can type immediately after opening search modal

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 02:12:41 +08:00
gbanyanandClaude 2c9d5ed650 Add full-text search with Chinese tokenization using Pagefind
Integrated Pagefind for static site search with built-in Chinese word segmentation support.

Changes:
1. **Installed Pagefind** (v1.4.0) as dev dependency
2. **Updated build script** to run Pagefind indexing after Next.js build
   - Indexes all 69 pages with 5,711 words
   - Automatic Chinese (zh-tw) language detection
3. **Created search modal component** (components/search-modal.tsx)
   - Dynamic Pagefind UI loading (lazy-loaded on demand)
   - Keyboard shortcuts (Cmd+K / Ctrl+K)
   - Chinese translations for UI elements
   - Dark mode compatible styling
4. **Added search button to header** (components/site-header.tsx)
   - Integrated SearchButton with keyboard shortcut display
   - Modal state management
5. **Custom Pagefind styles** (styles/globals.css)
   - Tailwind-based styling to match site design
   - Dark mode support
   - Highlight styling for search results

Features:
-  Full-text search across all blog posts and pages
-  Built-in Chinese word segmentation (Unicode-based)
-  Mixed Chinese/English query support
-  Zero bundle impact (20KB lazy-loaded on search activation)
-  Keyboard shortcuts (⌘K / Ctrl+K)
-  Search result highlighting with excerpts
-  Dark mode compatible

Technical Details:
- Pagefind runs post-build to index .next directory
- Search index stored in .next/pagefind/
- Chinese segmentation works automatically via Unicode boundaries
- No third-party services or API keys required

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 00:10:26 +08:00
gbanyanandClaude 912c70332e Fix tag URL encoding for non-ASCII characters
Fixed tag matching issue where tags with spaces and non-ASCII characters (like "Medicine - 醫學") were not working correctly on Vercel.

Changes:
1. Updated getTagSlug() to normalize tags without encoding - Next.js handles URL encoding automatically
2. Added decodeURIComponent() in tag page to decode incoming URL parameters
3. This ensures proper matching between generated slugs and URL parameters

The fix resolves:
- Tag archive pages showing wrong characters
- Articles not being collected under correct tags
- URL display issues with encoded characters

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 23:20:04 +08:00
gbanyanandClaude 5d3d754252 Fix tag URL encoding for non-ASCII characters
Updated getTagSlug() to properly encode tags with spaces and non-ASCII characters (like Chinese). The function now:
- Normalizes multiple spaces/dashes to single dashes
- Properly encodes non-ASCII characters using encodeURIComponent
- Prevents issues with URL encoding on Vercel deployment

This fixes tags like "Medicine - 醫學" being displayed as "medicine---%E9%86%AB%E5%AD%B8" by generating clean URLs like "medicine-%E9%86%AB%E5%AD%B8".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 23:10:34 +08:00
gbanyanandClaude 653f079e1a Upgrade ESLint to v9 to fix Vercel deployment
Updated ESLint from 8.57.1 to 9.39.1 to resolve peer dependency conflict with eslint-config-next@16.0.3 which requires ESLint >=9.0.0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 22:55:55 +08:00
gbanyan a4db9688b6 Upgrade to Next.js 16 with Turbopack and Contentlayer2
- Upgraded Next.js to v16, React to v19
- Migrated from contentlayer to contentlayer2
- Migrated to Turbopack by decoupling Contentlayer from webpack
- Updated all page components to handle async params (Next.js 15+ breaking change)
- Changed package.json to type: module and renamed config files to .cjs
- Updated README with current tech stack and article creation instructions
- Fixed tag encoding issue (removed double encoding)
- All security vulnerabilities resolved (npm audit: 0 vulnerabilities)
2025-11-19 22:43:14 +08:00
gbanyan 4c08413936 Migrate to Contentlayer2 2025-11-19 21:46:49 +08:00
gbanyan a249a120a5 Stage all layout updates 2025-11-19 17:38:45 +08:00
gbanyan 7ca7655e40 Add asset sync script 2025-11-19 17:31:18 +08:00
gbanyan 0d5fc93b30 Document serif headings and point submodule to GitHub 2025-11-19 17:12:11 +08:00
gbanyan 937203b4e9 docs: refresh README for new design 2025-11-19 02:31:37 +08:00
gbanyan 8ade752448 oops 2025-11-19 02:23:32 +08:00
gbanyan e04a03097f Convert favicon to actual PNG 2025-11-19 02:16:15 +08:00
gbanyan a8ee8d83af Update favicon to gravatar 2025-11-19 02:15:02 +08:00
gbanyan 261cb1d91e Add favicon 2025-11-19 02:13:23 +08:00
gbanyan f32206d390 Use next/image for hero/sidebar/markdown images 2025-11-19 02:07:35 +08:00
gbanyan ce43491e2e Switch card images to next/image 2025-11-19 02:03:49 +08:00
gbanyan 68ababe8c8 checkpoint before image optimizations 2025-11-19 02:02:34 +08:00
gbanyan 985caa2a4d Cleanup stray text in timeline wrapper 2025-11-19 01:56:59 +08:00
gbanyan 77bd180d97 Remove animated timeline dot 2025-11-19 01:55:56 +08:00
gbanyan 3425098006 Refine timeline rail/tick aesthetics 2025-11-19 01:49:40 +08:00
gbanyan eefc38d562 Add glow and animation to timeline 2025-11-19 01:46:37 +08:00
gbanyan 48ce66a3e6 Remove timeline arrow 2025-11-19 01:43:29 +08:00
gbanyan 22120595a6 Use only card-aligned timeline ticks 2025-11-19 01:41:12 +08:00
gbanyan eab80bd17a Render timeline ticks per card 2025-11-19 01:36:54 +08:00
gbanyan 5b99486a68 Style timeline rail with ticks and arrow 2025-11-19 01:31:02 +08:00
gbanyan 5fdd72302e Reduce gutter between timeline rail and cards 2025-11-19 01:25:19 +08:00
gbanyan 66cd9b8608 Remove timeline markers entirely 2025-11-19 01:24:12 +08:00
gbanyan 2e80b7ac59 Center timeline markers vertically 2025-11-19 01:22:49 +08:00
gbanyan be5d942c79 Align node ring visually with timeline rail 2025-11-19 01:17:33 +08:00
gbanyan 3018a25578 Turn timeline nodes into hollow rings 2025-11-19 01:14:06 +08:00
gbanyan 04182ec754 Align timeline nodes with brighter rail 2025-11-19 01:11:45 +08:00
gbanyan 9b2d754a2f Tighten timeline spacing and add white node 2025-11-19 01:07:25 +08:00
gbanyan 1a7ae8a269 Remove timeline node dot 2025-11-19 01:05:22 +08:00
gbanyan 9a7eb6cfe3 Center timeline nodes directly on rail 2025-11-19 01:04:08 +08:00
gbanyan 246646f176 Brighten timeline rail and align nodes 2025-11-19 01:00:18 +08:00
gbanyan 287c0d72a8 Refine timeline visuals and apply to blog list 2025-11-19 00:58:13 +08:00
gbanyan fe191752da Add aesthetic timeline to post lists 2025-11-19 00:54:58 +08:00
gbanyan 10e4e7e21e Give tags index a hero summary and card grid 2025-11-19 00:51:00 +08:00
gbanyan 82a459bede Restyle blockquotes with academic flair 2025-11-19 00:47:28 +08:00
gbanyan af0d2e3a6c Formalize font weight hierarchy 2025-11-19 00:42:53 +08:00
gbanyan 9235ab291b Expand system font stack for multilingual UI 2025-11-19 00:37:12 +08:00
gbanyan 79578252df Apply new type scale to TOC 2025-11-19 00:33:11 +08:00
gbanyan a225d57e06 Fix progress bar width 2025-11-19 00:30:35 +08:00
gbanyan b416c9eb7d Soften reading progress indicator 2025-11-19 00:28:09 +08:00
gbanyan 61d5092136 Let sidebar about text honor line breaks 2025-11-19 00:26:37 +08:00
gbanyan a582ef9cb5 Scale right sidebar typography 2025-11-19 00:24:16 +08:00
gbanyan dc5ca97fee Add fluid typography scale and responsive headings 2025-11-19 00:22:09 +08:00
gbanyan b4ee8b122f Remove dot icon from TOC items 2025-11-18 23:57:40 +08:00
gbanyan cd95a7bb79 Render TOC items as divs to eliminate bullets 2025-11-18 23:51:43 +08:00
gbanyan f34221b567 Exclude TOC from prose styling 2025-11-18 23:50:03 +08:00
gbanyan 3509b43643 Inline TOC list style overrides 2025-11-18 23:49:08 +08:00
gbanyan 6ca024b0ba Force TOC list styles with !important 2025-11-18 23:47:47 +08:00
gbanyan 9d86cd4663 Force TOC markers to be hidden 2025-11-18 23:46:20 +08:00
gbanyan 31f1c6979d Ensure TOC items have no default bullets 2025-11-18 23:44:24 +08:00
gbanyan b69755c2d6 Force TOC list to remove default bullets 2025-11-18 23:41:37 +08:00
gbanyan dadb5dce5c Remove default list bullets from TOC 2025-11-18 23:36:27 +08:00
gbanyan 7a6cd55c42 Polish TOC bullets 2025-11-18 23:34:38 +08:00
gbanyan 1e39647ab6 Fix duplicate imports in post TOC 2025-11-18 23:31:52 +08:00
gbanyan e73f37da76 Hide next station when no newer posts 2025-11-18 23:10:15 +08:00
gbanyan 351a1a2f70 Loosen scroll reveal trigger for mobile 2025-11-18 23:04:02 +08:00
gbanyan 80d0b236c5 Refine navigation and post UI 2025-11-18 17:34:05 +08:00
gbanyan c404be0822 Remove subtitles from storyline nav cards 2025-11-18 17:03:18 +08:00
gbanyan 71680252a4 Show only previous/next cards in storyline rail 2025-11-18 17:01:22 +08:00
gbanyan 3d3090c4e2 Hide subtitle on current storyline station 2025-11-18 16:59:33 +08:00
gbanyan 904434774b Streamline storyline rail into linear layout 2025-11-18 16:57:13 +08:00
gbanyan 91dec52db6 Refine storyline rail to minimalist arrow layout 2025-11-18 16:54:35 +08:00
gbanyan df10c8b751 Simplify storyline navigation aesthetics 2025-11-18 16:51:59 +08:00
gbanyan 009f4bf41e Add ESLint config and dependencies 2025-11-18 16:51:52 +08:00
gbanyan 96ebca37d6 Add storyline navigation rail for posts 2025-11-18 16:45:46 +08:00
gbanyan 4b3329d66f Add related posts section and blog search 2025-11-18 16:43:52 +08:00
gbanyan 0df0a85579 Refresh README to match current layout, color system, and content submodule workflow 2025-11-18 02:04:43 +08:00
gbanyan 00b45950a4 Increase right sidebar font sizes for better readability 2025-11-18 00:26:55 +08:00
gbanyan 42ea2de3bd Add env-based short about text under sidebar avatar and remove 'about site' card 2025-11-18 00:18:15 +08:00
gbanyan 8884328627 Increase navbar font size to base/lg scale 2025-11-17 23:43:13 +08:00
gbanyan 23421a2980 Enlarge home hero heading text size 2025-11-17 23:41:03 +08:00
gbanyan f844655628 Center home hero heading and tagline in main column 2025-11-17 23:36:50 +08:00
gbanyan f0e0e3d775 Slightly increase navbar link font size 2025-11-17 23:33:49 +08:00
gbanyan 9e94e78e28 Update content submodule to latest main 2025-11-17 23:31:33 +08:00
gbanyan 3332924b8e Use lighter accent color for navbar hover state 2025-11-17 23:22:57 +08:00
gbanyan 1804138124 Add hover/focus accent styles to navbar links 2025-11-17 23:21:29 +08:00
gbanyan 586e0bfdbc Align sidebar hot tags with neutral dark-mode styling 2025-11-17 23:17:23 +08:00
gbanyan 0c5c5e230c Improve dark-mode readability of tags using neutral backgrounds 2025-11-17 23:15:15 +08:00
gbanyan 6033d9f58a Apply accent-based tag styling to sidebar hot tags for better dark-mode readability 2025-11-17 23:11:25 +08:00
gbanyan 834ee6838d Make right-sidebar gravatar larger again 2025-11-17 23:07:41 +08:00
gbanyan 22d01bfee8 Increase gravatar size in right sidebar hero 2025-11-17 23:06:15 +08:00
gbanyan 193b5ced12 Revert layout shell width to original uniform container 2025-11-17 22:58:09 +08:00
gbanyan 4cb3e7627b Introduce env-driven accent color system and apply to links, icons, and tags 2025-11-17 22:46:55 +08:00
gbanyan e7a9d89cfc Further widen detail-page main column vs sidebar 2025-11-17 22:37:05 +08:00
gbanyan 8c7453dbcc Remove latest articles section from right sidebar 2025-11-17 22:24:49 +08:00
gbanyan 45e6088f69 Make single article pages use a wider main column than indexes 2025-11-17 22:21:54 +08:00
gbanyan 77c127756e Shrink TOC column and gap to give articles more width 2025-11-17 22:19:51 +08:00
gbanyan a952c3cdc1 Let single post/pages use full main column width 2025-11-17 22:16:43 +08:00
gbanyan 2db31ae1e1 Further widen content container slightly 2025-11-17 22:13:07 +08:00
gbanyan 08c36fb6a9 Slightly widen main content while keeping sidebar proportion 2025-11-17 22:11:05 +08:00
gbanyan 675f5de74f Narrow content width and slightly increase base typography size 2025-11-17 22:08:26 +08:00
gbanyan 593a5ff272 Add gravatar hero with social icons to right sidebar 2025-11-17 22:01:25 +08:00