Files
wiki/public/raw/changelog.md

98 KiB

Changelog


Type: page Date: 2026-01-10

All notable changes to this project.

v2.16.3

Released January 10, 2026

Social icons in hamburger menu and Dashboard Config alignment

Moved social icons from mobile header to hamburger menu for cleaner mobile UI. Added Dashboard Config options for socialFooter.showInHeader and askAI.enabled. Added configuration alignment documentation for AI/LLMs.

Changes:

  • Social icons now appear in hamburger menu below navigation links (mobile only)
  • Removed social icons from mobile header (cleaner mobile UI)
  • Added socialFooter.showInHeader toggle to Dashboard Config Social Footer card
  • Added new Ask AI config card with askAI.enabled toggle in Dashboard Config
  • Added "Configuration alignment" section to CLAUDE.md for AI/LLM guidance
  • Added sync comments to siteConfig.ts and Dashboard.tsx ConfigSection

Files changed:

  • src/components/MobileMenu.tsx - Added social icons section
  • src/components/Layout.tsx - Removed social icons from mobile-nav-controls
  • src/pages/Dashboard.tsx - Added socialFooterShowInHeader and askAIEnabled config
  • src/styles/global.css - Added mobile-menu-social CSS styles
  • src/config/siteConfig.ts - Added alignment comment
  • CLAUDE.md - Added Configuration alignment section

v2.16.2

Released January 10, 2026

Ask AI documentation alignment

Aligned Ask AI configuration across all config and documentation files. The Ask AI feature (header chat with RAG) is now properly documented alongside AI Agent and AI Dashboard features.

Changes:

  • Added askAI config to fork-config.json.example
  • Added Ask AI Configuration section to FORK_CONFIG.md
  • Added Ask AI (header chat) section to docs-dashboard.md
  • Added Ask AI (header chat) section to how-to-use-the-markdown-sync-dashboard.md

Files changed:

  • fork-config.json.example - Added askAI config block
  • FORK_CONFIG.md - Added Ask AI Configuration section
  • content/pages/docs-dashboard.md - Added Ask AI documentation
  • content/blog/how-to-use-the-markdown-sync-dashboard.md - Added Ask AI setup guide

v2.16.1

Released January 10, 2026

Docs layout scrollbar hiding

Hidden scrollbars on the docs section layout while preserving scroll functionality. Cleaner UI that matches the design without visible scrollbars.

Fixes:

  • Left sidebar scrolls but no scrollbar visible
  • Right sidebar scrolls but no scrollbar visible
  • Main docs content scrolls but no scrollbar visible
  • No browser page scrollbar on docs pages
  • Scrolling works via trackpad, mouse wheel, and touch

Technical:

  • Added body:has(.docs-layout) { overflow: hidden; } to prevent page-level scroll
  • Added scrollbar hiding rules for .docs-sidebar-left, .docs-sidebar-right, .docs-content
  • Cross-browser support: -ms-overflow-style: none (IE/Edge), scrollbar-width: none (Firefox), ::-webkit-scrollbar { width: 0 } (Chrome/Safari)

Files changed:

  • src/styles/global.css - Added scrollbar hiding rules and body overflow rule

v2.16.0

Released January 9, 2026

Version control system

Added a Sync version control system for tracking changes to posts, pages, home content, and footer.

Features:

  • 3-day version history for all content
  • Dashboard toggle to enable/disable version control
  • Version history modal with unified diff visualization
  • Preview mode to view previous version content
  • One-click restore with automatic backup of current state
  • Automatic cleanup of versions older than 3 days (daily cron at 3 AM UTC)
  • Version stats display in Config section

How to use:

  1. Navigate to Dashboard > Config
  2. Find the "Version Control" card
  3. Toggle "Enable version control" on
  4. Edit posts/pages or run sync commands to capture versions
  5. Click the History button in the editor to view version history
  6. Select a version to view diff or preview, then click "Restore This Version"

Technical:

  • New convex/versions.ts with 7 functions (isEnabled, setEnabled, createVersion, getVersionHistory, getVersion, restoreVersion, cleanupOldVersions, getStats)
  • New contentVersions table with indexes for efficient queries
  • New versionControlSettings table for toggle state
  • New VersionHistoryModal.tsx component using existing DiffCodeBlock
  • Version capture integrated into cms.ts, posts.ts, and pages.ts
  • Cleanup cron job in crons.ts

Files changed:

  • convex/schema.ts - Added contentVersions and versionControlSettings tables
  • convex/versions.ts - New file with all version control logic
  • convex/cms.ts - Added version capture before dashboard edits
  • convex/posts.ts - Added version capture before sync updates
  • convex/pages.ts - Added version capture before sync updates
  • convex/crons.ts - Added daily cleanup job
  • src/components/VersionHistoryModal.tsx - New version history modal
  • src/pages/Dashboard.tsx - Added Version Control config card and History button
  • src/styles/global.css - Added ~370 lines of version modal CSS

v2.15.3

Released January 9, 2026

Footer not displaying on /docs landing page fix

Fixed an issue where the footer was not displaying on the /docs landing page even when showFooter: true was set in the frontmatter. The DocsPage.tsx component (which handles the /docs route with docsLanding: true) was missing the Footer component entirely.

Fixes:

  • Added Footer component to DocsPage.tsx
  • Footer now respects showFooter frontmatter field on docs landing pages
  • Added AI chat support to docs landing page via aiChatEnabled and pageContent props

Technical:

  • Added Footer import and footerPage query to fetch footer content
  • Added footer rendering logic after BlogPost component (same pattern as Post.tsx)
  • Updated getDocsLandingPage query in convex/pages.ts to return showFooter, footer, excerpt, and aiChat fields
  • Updated getDocsLandingPost query in convex/posts.ts to return showFooter, footer, and aiChat fields

Files changed:

  • src/pages/DocsPage.tsx - Added Footer component and rendering logic
  • convex/pages.ts - Updated getDocsLandingPage query return fields
  • convex/posts.ts - Updated getDocsLandingPost query return fields

v2.15.2

Released January 8, 2026

Docs layout CSS conflict fix

Fixed a CSS conflict where the .main-content container was constraining the docs section layout to 800px max-width, preventing the three-column layout (left sidebar, content, right sidebar) from displaying correctly.

Fixes:

  • Left sidebar now properly flush left at left: 0
  • Right sidebar now properly flush right at right: 0
  • Docs content area properly positioned between sidebars
  • Responsive margins adjusted for all breakpoints

Technical:

  • Added .main-content:has(.docs-layout) CSS rule to expand to 100% width
  • Updated Layout.tsx to use main-content-wide class for docs pages
  • Fixed .docs-content margins: 280px (desktop), 240px (small tablet), 0 (mobile)
  • Added responsive margin adjustments at 1200px, 900px, 768px breakpoints

Files changed:

  • src/styles/global.css - Added docs layout override, fixed margin values
  • src/components/Layout.tsx - Added isDocsPage check for main-content-wide

v2.15.1

Released January 8, 2026

Additional Core Web Vitals CLS and INP improvements

Continued performance improvements targeting Cumulative Layout Shift (CLS), Largest Contentful Paint (LCP), and Interaction to Next Paint (INP).

CLS Fixes:

  • Added aspect-ratio: 16/10 to .blog-image to reserve space before images load
  • Added aspect-ratio: 16/9 to .post-header-image-img to prevent header image layout shift
  • Added contain: layout style to .main-content and .main-content-wide to isolate layout recalculations

LCP Improvements:

  • Added fetchPriority="high" to logo image in Layout.tsx for faster loading
  • Added fetchPriority="high" to header images (showImageAtTop) in Post.tsx

INP/Animation Improvements:

  • Added will-change: transform to continuous spin animations:
    • .spinner-icon
    • .animate-spin
    • .ai-chat-spinner
    • .ai-image-spinner
    • .spinning
    • .dashboard-import-btn .spin
  • Added will-change: transform to .logo-marquee-track for smoother marquee
  • Added will-change: opacity to .visitor-map-badge-dot for pulse animation

Files changed:

  • src/styles/global.css - CLS prevention, CSS containment, animation will-change hints
  • src/components/Layout.tsx - fetchPriority on logo
  • src/pages/Post.tsx - fetchPriority on header images

v2.15.0

Released January 7, 2026

Export as PDF

Added PDF export option to CopyPageDropdown. Users can now export any blog post or page as a clean, formatted PDF document using the browser's native print dialog.

Features:

  • Export as PDF button in Copy page dropdown (positioned at end of menu)
  • Clean formatted output without markdown syntax
  • Title displayed as proper heading
  • Metadata shown on single line (date, read time, tags)
  • Content with markdown stripped for readable document
  • Uses Phosphor FilePdf icon

Technical:

  • Added formatForPrint function to strip markdown syntax (headings, bold, italic, code, links, blockquotes)
  • Added handleExportPDF handler that opens styled print window
  • Imports FilePdf from @phosphor-icons/react (already installed in project)

Files changed:

  • src/components/CopyPageDropdown.tsx - New PDF export functionality

v2.14.1

Released January 7, 2026

Additional Core Web Vitals animation fixes

Continued performance improvements targeting non-composited animations identified by PageSpeed Insights.

Fixes:

  • Fixed docs-skeleton-pulse animation: Converted from background-position (non-composited) to pseudo-element with transform: translateX() (GPU-composited)
  • Added will-change hints to 6 more animated elements for GPU compositing

Elements with new will-change hints:

  • .image-lightbox-backdrop - will-change: opacity
  • .search-modal - will-change: transform, opacity
  • .ai-chat-message - will-change: transform, opacity
  • .dashboard-toast - will-change: transform, opacity
  • .ask-ai-modal - will-change: transform, opacity
  • .docs-article - will-change: opacity

Files changed:

  • src/styles/global.css - Skeleton animation fix, additional will-change hints

v2.14.0

Released January 7, 2026

Core Web Vitals performance optimizations

Fixes for PageSpeed Insights failures on mobile and desktop. These changes improve Largest Contentful Paint (LCP) and eliminate non-composited animation warnings.

Fixes:

  • Non-composited animations: Visitor map pulse animations now use GPU-composited transform: scale() instead of animating SVG r attribute
  • Duplicate keyframes: Removed 5 redundant @keyframes spin definitions from CSS
  • GPU compositing hints: Added will-change to animated elements (theme toggle, dropdown menus, modals, scroll-to-top button)

Performance additions:

  • Critical CSS inlined in index.html (~2KB) for instant first paint
  • Theme variables, reset styles, layout skeleton, and navigation pre-loaded
  • Additional preconnect hints for Convex site endpoints

Files changed:

  • src/styles/global.css - Animation fixes, will-change hints, removed duplicates
  • src/components/VisitorMap.tsx - Updated SVG circle radius for transform-based animation
  • index.html - Inline critical CSS, resource hints

v2.13.0

Released January 7, 2026

Enhanced diff code block rendering

Diff and patch code blocks now render with enhanced visualization powered by @pierre/diffs. This brings Shiki-based syntax highlighting specifically designed for showing code changes.

Features:

  • Unified view (default): Single column with +/- indicators
  • Split view: Side-by-side comparison of old and new code
  • View toggle button to switch between modes
  • Theme-aware colors matching dark/light/tan/cloud themes
  • Copy button for copying raw diff content
  • Automatic routing: Use diff or patch in markdown

New documentation:

  • Blog post: "How to Use Code Blocks" with examples of regular code blocks and diff rendering

Technical:

  • Added @pierre/diffs package
  • Created DiffCodeBlock component (src/components/DiffCodeBlock.tsx)
  • Updated BlogPost.tsx to route diff/patch blocks to new renderer
  • Added diff block CSS styles to global.css
  • Added vendor-diffs chunk to Vite config

v2.12.0

Released January 7, 2026

Canonical URL fix for search engines (GitHub Issue #6)

Fixed a mismatch where raw HTML was showing the homepage canonical URL instead of the page-specific canonical URL. Search engines that check raw HTML before rendering JavaScript now receive the correct canonical tags.

Changes:

  • Added search engine bot detection (Google, Bing, DuckDuckGo, etc.) to serve pre-rendered HTML
  • Search engines now receive correct canonical URLs in the initial HTML response
  • Added SEO Bot Configuration documentation in FORK_CONFIG.md and setup-guide.md
  • Bot detection arrays are easily customizable in netlify/edge-functions/botMeta.ts

For forkers:

The bot detection configuration is documented with clear comments at the top of botMeta.ts. You can customize which bots receive pre-rendered HTML by editing the SOCIAL_PREVIEW_BOTS, SEARCH_ENGINE_BOTS, and AI_CRAWLERS arrays.


v2.11.0

Released January 6, 2026

Ask AI header button with RAG-based Q&A

New header button that opens a chat modal for asking questions about site content. Uses semantic search to find relevant posts and pages, then generates AI responses with source citations.

Features:

  • Header button with sparkle icon (before search button)
  • Keyboard shortcuts: Cmd+J or Cmd+/ (Mac), Ctrl+J or Ctrl+/ (Windows/Linux)
  • Real-time streaming responses via Convex Persistent Text Streaming
  • Model selector: Claude Sonnet 4 (default) or GPT-4o
  • Markdown rendering with syntax highlighting
  • Internal links use React Router for seamless navigation
  • Source citations with links to referenced content
  • Copy response button (hover to reveal) for copying AI answers
  • Chat history within session (clears on page refresh)
  • Clear chat button to reset conversation

How it works:

  1. User question is stored in database with session ID
  2. Query is converted to embedding using OpenAI text-embedding-ada-002
  3. Vector search finds top 5 relevant posts/pages
  4. Content is sent to selected AI model with RAG system prompt
  5. Response streams in real-time with source citations appended

Configuration:

Enable in src/config/siteConfig.ts:

askAI: {
  enabled: true,
  defaultModel: "claude-sonnet-4-20250514",
  models: [
    { id: "claude-sonnet-4-20250514", name: "Claude Sonnet 4", provider: "anthropic" },
    { id: "gpt-4o", name: "GPT-4o", provider: "openai" },
  ],
},

Requirements:

  • semanticSearch.enabled: true (for embeddings)
  • OPENAI_API_KEY in Convex (for embeddings)
  • ANTHROPIC_API_KEY in Convex (for Claude models)
  • Run npm run sync to generate embeddings

Technical details:

  • New component: src/components/AskAIModal.tsx
  • New Convex files: convex/askAI.ts (mutations/queries), convex/askAI.node.ts (HTTP action)
  • New table: askAISessions with by_stream index
  • HTTP endpoint: /ask-ai-stream for streaming responses
  • Uses @convex-dev/persistent-text-streaming component
  • Separated Node.js runtime (askAI.node.ts) from regular runtime (askAI.ts)

Updated files: convex/schema.ts, convex/askAI.ts, convex/askAI.node.ts, convex/http.ts, convex/convex.config.ts, src/components/AskAIModal.tsx, src/components/Layout.tsx, src/config/siteConfig.ts, src/styles/global.css

v2.10.2

Released January 6, 2026

SEO fixes for GitHub Issue #4

Seven SEO issues resolved to improve search engine optimization:

  1. Canonical URL - Dynamic canonical link tags added client-side for posts and pages
  2. Single H1 per page - Markdown H1s demoted to H2 elements with .blog-h1-demoted class (maintains H1 visual styling)
  3. DOM order fix - Article now loads before sidebar in DOM for better SEO (CSS order property maintains visual layout)
  4. X-Robots-Tag - HTTP header added via netlify.toml (public routes indexed, dashboard/API routes noindexed)
  5. Hreflang tags - Self-referencing hreflang (en, x-default) for language targeting
  6. og:url consistency - Uses same canonicalUrl variable as canonical link tag
  7. twitter:site - New TwitterConfig in siteConfig.ts for Twitter Cards

Configuration:

Add your Twitter handle in src/config/siteConfig.ts:

twitter: {
  site: "@yourhandle",
  creator: "@yourhandle",
},

Updated files: src/config/siteConfig.ts, src/pages/Post.tsx, src/components/BlogPost.tsx, src/styles/global.css, convex/http.ts, netlify.toml, index.html, fork-config.json.example

v2.10.1

Released January 5, 2026

Optional semantic search configuration

Semantic search can now be disabled via siteConfig.semanticSearch.enabled:

semanticSearch: {
  enabled: false, // Disable semantic search, use keyword only
},

When disabled:

  • Search modal shows only keyword search (no mode toggle)
  • Embedding generation skipped during sync (saves API costs)
  • Existing embeddings preserved in database (no data loss)

Default is enabled: false (keyword search only, no API key required). Set to true and configure OPENAI_API_KEY to enable semantic search.

Updated files: src/config/siteConfig.ts, src/components/SearchModal.tsx, scripts/sync-posts.ts, src/pages/Dashboard.tsx, FORK_CONFIG.md, fork-config.json.example, content/pages/docs-semantic-search.md, content/pages/docs.md

v2.10.0

Released January 5, 2026

Semantic search with vector embeddings

Search now supports two modes accessible via Cmd+K:

  • Keyword search (existing) - Matches exact words using Convex full-text search. Instant, free, supports highlighting.
  • Semantic search (new) - Finds content by meaning using OpenAI embeddings. Toggle to "Semantic" mode in search modal.

How semantic search works:

  1. Your query is converted to a 1536-dimension vector using OpenAI text-embedding-ada-002
  2. Convex compares this vector to stored embeddings for all posts and pages
  3. Results ranked by similarity score (displayed as percentage)
  4. Top 15 results returned

When to use each mode:

Use Case Mode
Specific code, commands, exact phrases Keyword
Conceptual questions ("how do I deploy?") Semantic
Need to highlight matches on page Keyword
Not sure of exact terminology Semantic

Configuration:

Semantic search requires an OpenAI API key:

npx convex env set OPENAI_API_KEY sk-your-key-here
npm run sync  # Generates embeddings for all content

If OPENAI_API_KEY is not configured, semantic search returns empty results and keyword search continues to work normally.

Technical details:

  • New files: convex/embeddings.ts, convex/embeddingsQueries.ts, convex/semanticSearch.ts, convex/semanticSearchQueries.ts
  • Added embedding field and by_embedding vector index to posts and pages tables
  • SearchModal.tsx updated with Keyword/Semantic toggle (TextAa and Brain icons)
  • Embeddings generated automatically during npm run sync
  • Cost: ~$0.0001 per search query (embedding generation)

Updated files: convex/schema.ts, convex/embeddings.ts, convex/embeddingsQueries.ts, convex/semanticSearch.ts, convex/semanticSearchQueries.ts, src/components/SearchModal.tsx, scripts/sync-posts.ts, src/styles/global.css, content/pages/docs-search.md, content/pages/docs-semantic-search.md

v2.9.0

Released January 4, 2026

Dashboard Cloud CMS Features

The Dashboard now functions as a WordPress-style cloud CMS, allowing content creation and editing directly in the database without requiring the markdown file sync workflow.

Dual Source Architecture:

  • Dashboard-created content marked with source: "dashboard"
  • Markdown-synced content marked with source: "sync"
  • Both coexist independently in the database
  • Sync operations only affect synced content (dashboard content protected)
  • Source badges in Posts and Pages list views (blue "Dashboard", gray "Synced")

Direct Database Operations:

  • "Save to DB" button in Write Post/Page sections saves directly to database
  • "Save Changes" button in Post/Page editor updates content immediately
  • Delete button for dashboard-created content (synced content protected)
  • Changes appear instantly without requiring sync

Delete Confirmation Modal:

  • Warning modal displayed before deleting posts or pages
  • Shows item name and type being deleted
  • Themed to match dashboard UI with danger button styling
  • Backdrop click and Escape key to cancel

Rich Text Editor:

  • Three editing modes: Markdown (default), Rich Text (Quill WYSIWYG), Preview
  • Quill-based editor with formatting toolbar
  • Toolbar: headers (H1-H3), bold, italic, strikethrough, blockquote, code, lists, links
  • Automatic HTML-to-Markdown conversion when switching modes
  • Theme-aware styling using CSS variables

Server-Side URL Import:

  • Direct database import via Firecrawl (no file sync needed)
  • Enter URL in Import section, content is scraped and saved to database
  • Optional "Publish immediately" checkbox
  • Imported posts tagged with imported by default
  • Requires FIRECRAWL_API_KEY in Convex environment variables

Export to Markdown:

  • Export any post/page to .md file with complete frontmatter
  • Bulk export script: npm run export:db (dev) or npm run export:db:prod (prod)
  • Use for backup or converting dashboard content to file-based workflow

Technical details:

  • New file: convex/cms.ts with CRUD mutations
  • New file: convex/importAction.ts with Firecrawl server-side action
  • New file: scripts/export-db-posts.ts for bulk markdown export
  • Added source field and by_source index to posts and pages tables
  • Added ConfirmDeleteModal component to Dashboard.tsx
  • Fixed list row grid layout for proper source badge display

Updated files: convex/schema.ts, convex/posts.ts, convex/pages.ts, convex/cms.ts, convex/importAction.ts, scripts/export-db-posts.ts, src/pages/Dashboard.tsx, src/styles/global.css, package.json, content/pages/docs-dashboard.md

v2.8.7

Released January 4, 2026

Write page frontmatter sidebar toggle fix

  • Frontmatter sidebar toggle now works outside focus mode
    • Grid layout adjusts properly when frontmatter sidebar is collapsed
    • Previously only worked in focus mode due to missing CSS rules
    • Both sidebars can now be collapsed independently or together

Technical details:

  • Added .write-layout.frontmatter-collapsed CSS rule (grid-template-columns: 220px 1fr 56px)
  • Added .write-layout.sidebar-collapsed.frontmatter-collapsed CSS rule for both sidebars collapsed
  • Added responsive tablet styles for frontmatter collapsed state

Updated files: src/styles/global.css

v2.8.6

Released January 4, 2026

Fork configuration improvements

  • Fork configuration script now updates 14 files (was 11)
    • Added src/pages/DocsPage.tsx (SITE_URL constant)
    • Added netlify/edge-functions/mcp.ts (SITE_URL, SITE_NAME, MCP_SERVER_NAME)
    • Added scripts/send-newsletter.ts (default SITE_URL)
    • Improved public/openapi.yaml handling for all example URLs
  • Logo gallery hrefs now use relative URLs instead of hardcoded markdown.fast URLs
  • Updated fork-config.json.example with missing options (statsPage, mcpServer, imageLightbox)

Updated files: scripts/configure-fork.ts, src/config/siteConfig.ts, FORK_CONFIG.md, content/blog/fork-configuration-guide.md, fork-config.json.example

v2.8.5

Released January 3, 2026

Search result highlighting and scroll-to-match

  • Clicking a search result now navigates to the exact match location (not just the nearest heading)
  • All matching text is highlighted with theme-appropriate colors
  • Highlights pulse on arrival, then fade to subtle background after 4 seconds
  • Press Escape to clear highlights
  • Works across all four themes (dark, light, tan, cloud)

Technical details:

  • New useSearchHighlighting.ts hook with polling mechanism to wait for content load
  • Search query passed via ?q= URL parameter instead of hash anchor
  • Theme-specific highlight colors matching existing design system

Updated files: src/hooks/useSearchHighlighting.ts (new), src/components/SearchModal.tsx, src/components/BlogPost.tsx, src/pages/Post.tsx, src/styles/global.css

v2.8.4

Released January 3, 2026

AI service links now use local /raw URLs

  • ChatGPT, Claude, and Perplexity links now use local /raw/{slug}.md URLs instead of GitHub raw URLs
  • Simplified AI prompt from multi-line instructions to "Read this URL and summarize it:"
  • No longer requires git push for AI links to work (synced content available immediately)

Technical details:

  • Updated URL construction to use window.location.origin for consistency
  • Removed unused siteConfig import and getGitHubRawUrl function

Updated files: src/components/CopyPageDropdown.tsx

v2.8.3

Released January 3, 2026

Raw index.md now includes home.md and footer.md content

  • raw/index.md now mirrors the actual homepage structure
    • Home intro content from content/pages/home.md displays at top
    • Footer content from content/pages/footer.md displays at bottom
    • Horizontal rule separators between sections
    • Falls back to generic message if home-intro page not found
  • AI agents reading /raw/index.md now get the full homepage experience

Technical details:

  • Updated generateHomepageIndex function in scripts/sync-posts.ts
  • Finds home-intro and footer pages from published pages array by slug

Updated files: scripts/sync-posts.ts

v2.8.2

Released January 3, 2026

Footer fix for docs section pages

  • Fixed footer not displaying on docs section posts/pages even with showFooter: true in frontmatter
    • Post.tsx now fetches footer.md content from Convex (matching Home.tsx and Blog.tsx pattern)
    • Footer falls back to footer.md content when no per-post footer: frontmatter is specified
    • Priority order: per-post frontmatter footer: > synced footer.md content > siteConfig.footer.defaultContent

Technical details:

  • Added useQuery(api.pages.getPageBySlug, { slug: "footer" }) to Post.tsx
  • Updated all 4 Footer component calls to use post.footer || footerPage?.content pattern

Updated files: src/pages/Post.tsx

v2.8.1

Released January 3, 2026

Centralized defaultTheme in siteConfig.ts

  • Theme configuration moved from ThemeContext.tsx to siteConfig.ts
  • New defaultTheme field in siteConfig for centralized theme management
  • ThemeContext.tsx now imports theme setting from siteConfig
  • Fork configuration script updated to modify siteConfig.ts
  • Backward compatible: falls back to "tan" if defaultTheme not set

Configuration example:

export const siteConfig: SiteConfig = {
  // ... other config
  defaultTheme: "tan", // Options: "dark", "light", "tan", "cloud"
};

Technical details:

  • Added Theme type export to src/config/siteConfig.ts
  • Added defaultTheme?: Theme field to SiteConfig interface
  • Updated src/context/ThemeContext.tsx to import from siteConfig
  • Renamed updateThemeContext to updateThemeConfig in scripts/configure-fork.ts

Updated files: src/config/siteConfig.ts, src/context/ThemeContext.tsx, scripts/configure-fork.ts, content/pages/docs.md, content/blog/setup-guide.md, FORK_CONFIG.md, content/blog/fork-configuration-guide.md

v2.8.0

Released January 3, 2026

Docs sidebar group icons via frontmatter

  • New docsSectionGroupIcon frontmatter field for docs sidebar group icons
    • Display Phosphor icons next to docs sidebar group titles
    • Icon appears left of the expand/collapse chevron
    • 55 supported icon names (Rocket, Book, PuzzlePiece, Gear, Code, etc.)
    • Icon weight: regular, size: 16px
    • Only one item per group needs to specify the icon
    • Graceful fallback if icon name not recognized

Example usage:

---
docsSection: true
docsSectionGroup: "Getting Started"
docsSectionGroupOrder: 1
docsSectionGroupIcon: "Rocket"
docsSectionOrder: 1
---

Technical details:

  • Updated convex/schema.ts with docsSectionGroupIcon field in posts and pages tables
  • Updated convex/posts.ts and convex/pages.ts queries and mutations
  • Updated scripts/sync-posts.ts to parse docsSectionGroupIcon from frontmatter
  • Updated src/components/DocsSidebar.tsx with Phosphor icon imports and rendering
  • Added CSS styles for .docs-sidebar-group-icon
  • Updated .claude/skills/frontmatter.md with icon documentation

Updated files: convex/schema.ts, convex/posts.ts, convex/pages.ts, scripts/sync-posts.ts, src/components/DocsSidebar.tsx, src/styles/global.css, .claude/skills/frontmatter.md, files.md, TASK.md, changelog.md, content/pages/docs.md, public/raw/setup-guide.md

v2.7.0

Released January 2, 2026

Docs sidebar group ordering

  • New docsSectionGroupOrder frontmatter field for controlling docs sidebar group order
  • Groups are sorted by the minimum docsSectionGroupOrder value among items in each group
  • Lower numbers appear first, groups without this field sort alphabetically
  • Works alongside docsSection, docsSectionGroup, and docsSectionOrder fields

Example usage:

---
docsSection: true
docsSectionGroup: "Getting Started"
docsSectionGroupOrder: 1
docsSectionOrder: 1
---

Technical details:

  • Updated convex/schema.ts with docsSectionGroupOrder field in posts and pages tables
  • Updated convex/posts.ts and convex/pages.ts queries and mutations
  • Updated scripts/sync-posts.ts to parse docsSectionGroupOrder from frontmatter
  • Updated src/components/DocsSidebar.tsx to sort groups by docsSectionGroupOrder

v2.6.0

Released January 1, 2026

Multi-model AI chat and image generation in Dashboard

  • AI Agent section with tab-based UI (Chat and Image Generation tabs)
  • Multi-model selector for text chat
    • Claude Sonnet 4 (Anthropic)
    • GPT-4o (OpenAI)
    • Gemini 2.0 Flash (Google)
  • Lazy API key validation: errors only shown when user tries to use a specific model
  • Each provider has friendly setup instructions with links to get API keys
  • AI Image Generation tab
    • Generate images using Gemini models (Nano Banana and Nano Banana Pro)
    • Aspect ratio selector (1:1, 16:9, 9:16, 4:3, 3:4)
    • Generated images stored in Convex storage with session tracking
    • Markdown-rendered error messages with setup instructions
  • New aiDashboard configuration in siteConfig
    • enableImageGeneration: Toggle image generation tab
    • defaultTextModel: Set default AI model for chat
    • textModels: Configure available text chat models
    • imageModels: Configure available image generation models

Technical details:

  • New file: convex/aiImageGeneration.ts for Gemini image generation action
  • New table: aiGeneratedImages in schema for tracking generated images
  • Updated convex/aiChatActions.ts with multi-provider support
    • Added callAnthropicApi, callOpenAIApi, callGeminiApi helper functions
    • Added getProviderFromModel to determine provider from model ID
    • Added getApiKeyForProvider for lazy API key retrieval
    • Added getNotConfiguredMessage for provider-specific setup instructions
  • Updated src/components/AIChatView.tsx with selectedModel prop
  • Updated src/pages/Dashboard.tsx with new AI Agent section
    • Tab-based UI for Chat and Image Generation
    • Model dropdowns with provider labels
    • Aspect ratio selector for image generation
  • CSS styles for AI Agent section in src/styles/global.css
    • .ai-agent-tabs, .ai-agent-tab for tab navigation
    • .ai-model-selector, .ai-model-dropdown for model selection
    • .ai-aspect-ratio-selector for aspect ratio options
    • .ai-generated-image, .ai-image-error, .ai-image-loading for image display

Environment Variables:

  • ANTHROPIC_API_KEY: Required for Claude models
  • OPENAI_API_KEY: Required for GPT-4o
  • GOOGLE_AI_API_KEY: Required for Gemini text chat and image generation

Updated files: convex/aiImageGeneration.ts, convex/aiChatActions.ts, convex/aiChats.ts, convex/schema.ts, src/components/AIChatView.tsx, src/pages/Dashboard.tsx, src/config/siteConfig.ts, src/styles/global.css, files.md, TASK.md, changelog.md, content/pages/changelog-page.md

v2.5.0

Released January 1, 2026

Social footer icons in header navigation

  • New showInHeader option in siteConfig.socialFooter to display social icons in the header
    • Social icons appear left of the search icon on desktop viewports
    • Uses same icons and links as the social footer component
    • Configurable via siteConfig, FORK_CONFIG.md, and fork-config.json
    • Set showInHeader: true in socialFooter config to enable

Technical details:

  • Exported platformIcons from src/components/SocialFooter.tsx for reuse
  • Added social icon rendering in src/components/Layout.tsx header controls
  • Added .header-social-links and .header-social-link CSS styles
  • Updated SocialFooterConfig interface with showInHeader: boolean
  • Added socialFooter support to scripts/configure-fork.ts

Updated files: src/config/siteConfig.ts, src/components/SocialFooter.tsx, src/components/Layout.tsx, src/styles/global.css, scripts/configure-fork.ts, FORK_CONFIG.md, fork-config.json.example, public/raw/docs.md, public/raw/setup-guide.md, files.md, TASK.md, changelog.md, content/pages/changelog-page.md

v2.4.0

Released January 1, 2026

YouTube and Twitter/X embed support

  • Embed YouTube videos and Twitter/X posts directly in markdown
    • Domain whitelisting for security (only trusted domains allowed)
    • Whitelisted domains: youtube.com, www.youtube.com, youtube-nocookie.com, www.youtube-nocookie.com, platform.twitter.com, platform.x.com
    • Auto-adds sandbox and loading="lazy" attributes for security
    • Non-whitelisted iframes silently blocked
    • Works on both blog posts and pages
  • Embeds section added to markdown-with-code-examples.md with usage examples

Technical details:

  • Added ALLOWED_IFRAME_DOMAINS constant in src/components/BlogPost.tsx
  • Added iframe to sanitize schema with allowed attributes
  • Added custom iframe component handler with URL validation
  • Added .embed-container CSS styles for responsive embeds

Updated files: src/components/BlogPost.tsx, src/styles/global.css, content/blog/markdown-with-code-examples.md, files.md, TASK.md, changelog.md, content/pages/changelog-page.md

v2.3.0

Released December 31, 2025

Author pages feature

  • Author archive pages at /author/:authorSlug displaying all posts by that author
    • Click on any author name in a post to view all their posts
    • View mode toggle (list/cards) with localStorage persistence
    • Mobile responsive layout matching tag pages design
    • Sitemap updated to include all author pages dynamically
  • New Convex queries for author data
    • getAllAuthors: Returns all unique authors with post counts
    • getPostsByAuthor: Returns posts by a specific author slug
  • Author name links in post headers
    • Author names now clickable with hover underline effect
    • Works on both blog posts and pages with authorName field
  • Follows existing tag pages pattern for consistent UX

Technical details:

  • Added by_authorName index to posts table in convex/schema.ts
  • New queries in convex/posts.ts: getAllAuthors, getPostsByAuthor
  • New component: src/pages/AuthorPage.tsx (based on TagPage.tsx pattern)
  • Added route /author/:authorSlug in src/App.tsx
  • Updated src/pages/Post.tsx to make authorName a clickable Link
  • Added author link and page styles to src/styles/global.css
  • Added author pages to sitemap in convex/http.ts

Updated files: convex/schema.ts, convex/posts.ts, convex/http.ts, src/pages/AuthorPage.tsx, src/App.tsx, src/pages/Post.tsx, src/styles/global.css, files.md, prds/authorname-blogs.md

v2.2.2

Released December 31, 2025

Homepage intro loading flash fix

  • Removed visible loading states from homepage intro content
    • No more "Loading..." text flash when app loads (fixed Suspense fallback in main.tsx)
    • No more bio text flash while home intro content loads (fixed conditional in Home.tsx)
    • Home intro content now appears without any visible loading state or fallback
    • Matches the loading pattern used by Post.tsx for docs pages (render nothing while loading)

Updated files: src/main.tsx, src/pages/Home.tsx, changelog.md, content/pages/changelog-page.md, TASK.md, files.md

v2.2.1

Released December 31, 2025

ES module compatibility fix for configure-fork.ts

  • Fixed __dirname is not defined error when running npm run configure
  • Added fileURLToPath import from url module to create ES module equivalent of __dirname
  • Script now works correctly with "type": "module" in package.json

Updated files: scripts/configure-fork.ts, files.md, changelog.md, content/pages/changelog-page.md, TASK.md

v2.2.0

Released December 30, 2025

Footer content via markdown page

  • New content/pages/footer.md for managing footer content via markdown sync
    • Footer content syncs with npm run sync without redeploy needed
    • Edit footer text, links, and formatting through markdown instead of code
    • Falls back to siteConfig.footer.defaultContent when page not found
    • Set showInNav: false to hide from navigation (page remains accessible via direct URL)
    • Supports full markdown including links, paragraphs, and line breaks

Technical details:

  • New file: content/pages/footer.md with frontmatter (slug: "footer", showInNav: false)
  • Updated: src/pages/Home.tsx to fetch footer page by slug "footer"
  • Updated: src/pages/Blog.tsx to fetch footer page by slug "footer"
  • Footer component now prioritizes page content over siteConfig.defaultContent
  • Pattern matches home-intro page for consistent content management

Updated files: content/pages/footer.md, src/pages/Home.tsx, src/pages/Blog.tsx, files.md, changelog.md, content/pages/changelog-page.md, FORK_CONFIG.md, TASK.md

v2.1.0

Released December 30, 2025

CLAUDE.md and Claude skills documentation

  • CLAUDE.md for Claude Code project instructions
    • Project context and quick start guide
    • All available npm commands and workflows
    • Code conventions and "do not" list
    • Key file references and project structure
    • Links to detailed skills documentation
  • Claude skills documentation in .claude/skills/ directory
    • frontmatter.md: Complete frontmatter syntax with all 25+ field options for posts and pages
    • convex.md: Convex patterns specific to this app (indexes, idempotent mutations, write conflict prevention)
    • sync.md: How sync commands work and content flow from markdown to Convex database
  • Automated CLAUDE.md updates via sync-discovery-files.ts
    • CLAUDE.md status comment updated during npm run sync:discovery
    • Includes current site name, post count, page count, and last updated timestamp
  • Unlisted posts feature
    • New unlisted frontmatter field for blog posts
    • Set unlisted: true to hide posts from listings while keeping them accessible via direct link
    • Unlisted posts are excluded from: blog listings, featured sections, tag pages, search results, and related posts
    • Posts remain accessible via direct URL (e.g., /blog/post-slug)
    • Useful for draft posts, private content, or posts you want to share via direct link only

Technical details:

  • New file: CLAUDE.md in project root
  • New directory: .claude/skills/ with three markdown files
  • Updated: scripts/sync-discovery-files.ts to update CLAUDE.md alongside AGENTS.md and llms.txt
  • Updated: convex/schema.ts - Added unlisted optional boolean field to posts table
  • Updated: convex/posts.ts - All listing queries filter out unlisted posts
  • Updated: convex/search.ts - Search excludes unlisted posts from results
  • Updated: scripts/sync-posts.ts - Added unlisted to interfaces and parsing logic
  • Updated: src/pages/Write.tsx - Added unlisted to POST_FIELDS frontmatter reference
  • Updated documentation: .claude/skills/frontmatter.md, content/pages/docs.md, content/blog/setup-guide.md, files.md

Updated files: CLAUDE.md, .claude/skills/frontmatter.md, .claude/skills/convex.md, .claude/skills/sync.md, scripts/sync-discovery-files.ts, convex/schema.ts, convex/posts.ts, convex/search.ts, scripts/sync-posts.ts, src/pages/Write.tsx, files.md, changelog.md, content/pages/changelog-page.md

v2.0.0

Released December 29, 2025

Markdown sync v2 complete

  • Full markdown content synchronization system
  • Real-time sync from markdown files to Convex database
  • Dashboard UI for content management
  • Sync server for executing sync commands from UI
  • Complete type safety across all Convex functions
  • Security improvements and optimizations

Technical details:

  • Optimized recordPageView mutation to reduce unnecessary reads
  • All mutations follow Convex best practices for write conflict prevention
  • Type-safe Convex functions with proper validators
  • Security review completed with all endpoints properly secured

v1.47.0

Released December 29, 2025

Image lightbox for blog posts and pages

  • Images automatically open in full-screen lightbox when clicked (if enabled)
  • Lightbox includes dark backdrop, close button (X icon), and caption display
  • Keyboard support: Press Escape to close lightbox
  • Click outside image (backdrop) to close
  • Alt text displayed as caption below image in lightbox
  • Images show pointer cursor (zoom-in) and subtle hover effect when lightbox is enabled
  • Configurable via siteConfig.imageLightbox.enabled (default: true)
  • Dashboard config generator includes image lightbox toggle
  • Responsive design: lightbox adapts to mobile screens

Configuration:

// src/config/siteConfig.ts
imageLightbox: {
  enabled: true, // Set to false to disable image lightbox
},

Technical details:

  • New ImageLightbox component in BlogPost.tsx with backdrop, close button, and keyboard handlers
  • Lightbox state management using React hooks (useState, useEffect)
  • CSS styles for lightbox backdrop, image container, close button, and caption
  • Prevents body scrolling when lightbox is open
  • Smooth fade-in animation for lightbox appearance

Updated files: src/components/BlogPost.tsx, src/config/siteConfig.ts, src/styles/global.css, src/pages/Dashboard.tsx, content/pages/docs.md, content/blog/setup-guide.md

v1.46.0

Released December 29, 2025

Dashboard sync server for executing sync commands from UI

  • Local HTTP server for executing sync commands directly from dashboard
    • Run npm run sync-server to start the local server on localhost:3001
    • Execute sync commands without opening a terminal
    • Real-time output streaming in dashboard terminal view
    • Server status indicator shows online/offline status
    • Copy and Execute buttons for each sync command
    • Optional token authentication via SYNC_TOKEN environment variable
    • Whitelisted commands only for security
    • Health check endpoint for server availability detection
    • Header sync buttons automatically use sync server when available
    • Copy icons for npm run sync-server command throughout dashboard

Technical details:

  • New scripts/sync-server.ts file implements local HTTP server
  • Uses Node.js child_process.spawn to execute npm commands
  • Streams output in real-time to dashboard UI
  • CORS enabled for localhost:5173 development server
  • Server binds to localhost only (not accessible from network)

Updated files: scripts/sync-server.ts, src/pages/Dashboard.tsx, src/styles/global.css, package.json

v1.45.0

Released December 29, 2025

Dashboard and WorkOS authentication integration

  • Dashboard supports optional WorkOS authentication via siteConfig.dashboard.requireAuth
  • WorkOS is optional - dashboard works with or without WorkOS configured
  • When requireAuth is false, dashboard is open access
  • When requireAuth is true and WorkOS is configured, dashboard requires login
  • Shows setup instructions if requireAuth is true but WorkOS is not configured
  • Warning banner displayed when authentication is not enabled
  • Blog posts added: "How to use the Markdown sync dashboard" and "How to setup WorkOS"

Updated files: src/pages/Dashboard.tsx, src/main.tsx, src/App.tsx, src/pages/Callback.tsx, src/utils/workos.ts, convex/auth.config.ts, src/config/siteConfig.ts, README.md, content/pages/docs.md, content/blog/setup-guide.md, FORK_CONFIG.md, fork-config.json.example, files.md, TASK.md, changelog.md, content/pages/changelog-page.md

v1.44.0

Released December 29, 2025

Dashboard for centralized content management and site configuration

  • Dashboard at /dashboard provides a centralized UI for managing content, configuring the site, and performing sync operations
  • Content management: Posts and Pages list views with filtering, search, pagination, and items per page selector (15, 25, 50, 100)
  • Post and Page editor: Markdown editor with live preview, draggable/resizable frontmatter sidebar (200px-600px), independent scrolling, download markdown, copy to clipboard
  • Write Post and Write Page: Full-screen writing interface with markdown editor, frontmatter reference, download markdown, localStorage persistence
  • AI Agent section: Dedicated AI chat separate from Write page, uses Anthropic Claude API, per-session chat history, markdown rendering
  • Newsletter management: All Newsletter Admin features integrated (subscribers, send newsletter, write email, recent sends, email stats)
  • Content import: Firecrawl import UI for importing external URLs as markdown drafts
  • Site configuration: Config Generator UI for all siteConfig.ts settings, generates downloadable config file
  • Index HTML editor: View and edit index.html content with meta tags, Open Graph, Twitter Cards, JSON-LD
  • Analytics: Real-time stats dashboard (clone of /stats page, always accessible in dashboard)
  • Sync commands: UI with buttons for all sync operations (sync, sync:discovery, sync:all for dev and prod)
  • Header sync buttons: Quick sync buttons in dashboard header for npm run sync:all (dev and prod)
  • Dashboard search: Search bar in header to search dashboard features, page titles, and post content
  • Toast notifications: Success, error, info, and warning notifications with auto-dismiss
  • Command modal: Shows sync command output with copy to clipboard functionality
  • Mobile responsive: Fully responsive design with mobile-optimized layout
  • Theme and font: Theme toggle and font switcher with persistent preferences

Updated files: src/pages/Dashboard.tsx, src/styles/global.css, src/App.tsx

v1.43.0

Released December 29, 2025

Stats page configuration option for public/private access

  • New StatsPageConfig interface in siteConfig.ts with enabled and showInNav options
  • Stats page can be made private by setting enabled: false (similar to NewsletterAdmin pattern)
  • When disabled, route shows "Stats page is disabled" message instead of analytics
  • Navigation item automatically hidden when stats page is disabled
  • Default configuration: enabled: true (public), showInNav: true (visible in nav)

Updated files: src/config/siteConfig.ts, src/App.tsx, src/pages/Stats.tsx, src/components/Layout.tsx

v1.42.0

Released December 29, 2025

Honeypot bot protection for contact and newsletter forms

  • Hidden honeypot fields invisible to humans but visible to bots
  • Contact form uses hidden "Website" field for bot detection
  • Newsletter signup uses hidden "Fax" field for bot detection
  • Bots that fill hidden fields receive fake success message (no data submitted)
  • No external dependencies required (client-side only protection)
  • Works with all four themes (dark, light, tan, cloud)

Updated files: src/components/ContactForm.tsx, src/components/NewsletterSignup.tsx

  • Honeypot fields use CSS positioning (position: absolute, left: -9999px) to hide from users
  • Fields include aria-hidden="true" and tabIndex={-1} for accessibility
  • Different field names per form (website/fax) to avoid pattern detection

v1.41.0

Released December 28, 2025

Blog heading styles for home intro content

  • Headings (h1-h6) in content/pages/home.md now use same styling as blog posts
  • Classes: blog-h1, blog-h2, blog-h3, blog-h4, blog-h5, blog-h6
  • Clickable anchor links (#) appear on hover for each heading
  • Automatic ID generation from heading text for anchor navigation
  • Additional blog styling for lists, blockquotes, horizontal rules, and links
  • Home intro headings now match blog post typography and spacing

Updated files: src/pages/Home.tsx

v1.39.0

Released December 28, 2025

HTTP-based MCP Server

  • Model Context Protocol (MCP) server deployed on Netlify Edge Functions
    • Accessible 24/7 at https://www.markdown.fast/mcp
    • No local machine required (unlike stdio-based MCP servers)
    • Works with Cursor, Claude Desktop, and other MCP-compatible clients
  • Public access with Netlify built-in rate limiting (50 req/min per IP)
  • Optional API key authentication for higher limits (1000 req/min)
    • Set MCP_API_KEY in Netlify environment variables
    • Add Authorization: Bearer <key> header to requests
  • Read-only access to blog content:
    • list_posts: Get all published posts with metadata
    • get_post: Get single post by slug with full content
    • list_pages: Get all published pages
    • get_page: Get single page by slug with full content
    • get_homepage: Get homepage data with featured and recent posts
    • search_content: Full text search across posts and pages
    • export_all: Batch export all content

Documentation

  • Blog post: "How to Use the MCP Server" with client configuration examples
  • MCP Server section added to docs.md
  • MCP configuration added to siteConfig.ts
  • Setup guide updated with MCP server section

Configuration

Add to Cursor (~/.cursor/mcp.json):

{
  "mcpServers": {
    "markdown-fast": {
      "url": "https://www.markdown.fast/mcp"
    }
  }
}

Updated files: netlify/edge-functions/mcp.ts, netlify.toml, package.json, src/config/siteConfig.ts, content/blog/how-to-use-mcp-server.md, content/pages/docs.md, content/blog/setup-guide.md, files.md, changelog.md, content/pages/changelog-page.md

v1.38.0

Released December 27, 2025

Newsletter CLI improvements

  • newsletter:send now calls scheduleSendPostNewsletter mutation directly
    • Sends emails in the background instead of printing instructions
    • Provides clear success/error feedback
    • Shows helpful messages about checking Newsletter Admin for results
  • New newsletter:send:stats command
    • Sends weekly stats summary to your inbox on demand
    • Uses scheduleSendStatsSummary mutation
    • Email sent to AGENTMAIL_INBOX or AGENTMAIL_CONTACT_EMAIL
  • New mutation scheduleSendStatsSummary in convex/newsletter.ts
    • Allows CLI to trigger stats summary sending
    • Schedules sendWeeklyStatsSummary internal action

Documentation

  • Blog post: "How to use AgentMail with Markdown Sync"
    • Complete setup guide for AgentMail integration
    • Environment variables configuration
    • Newsletter and contact form features
    • CLI commands documentation
    • Troubleshooting section
  • Updated docs.md with new CLI commands
  • Updated files.md with new script reference
  • Verified all AgentMail features use environment variables (no hardcoded emails)

Updated files: scripts/send-newsletter.ts, scripts/send-newsletter-stats.ts, convex/newsletter.ts, package.json, content/blog/how-to-use-agentmail.md, content/pages/docs.md, files.md, changelog.md, content/pages/changelog-page.md, TASK.md

v1.37.0

Released December 27, 2025

Newsletter Admin UI

  • Newsletter Admin UI at /newsletter-admin
    • Three-column layout similar to Write page
    • View all subscribers with search and filter (all/active/unsubscribed)
    • Stats showing active, total, and sent newsletter counts
    • Delete subscribers directly from admin
    • Send newsletter panel with two modes:
      • Send Post: Select a blog post to send as newsletter
      • Write Email: Compose custom email with markdown support
    • Markdown-to-HTML conversion for custom emails (headers, bold, italic, links, lists)
    • Copy icon on success messages to copy CLI commands
    • Theme-aware success/error styling (no hardcoded green)
    • Recent newsletters list showing sent history
    • Configurable via siteConfig.newsletterAdmin

Weekly Digest automation

  • Cron job runs every Sunday at 9:00 AM UTC
  • Automatically sends all posts published in the last 7 days
  • Uses AgentMail SDK for email delivery
  • Configurable via siteConfig.weeklyDigest

Developer Notifications

  • New subscriber alerts sent via email when someone subscribes
  • Weekly stats summary sent every Monday at 9:00 AM UTC
  • Uses AGENTMAIL_CONTACT_EMAIL or AGENTMAIL_INBOX as recipient
  • Configurable via siteConfig.newsletterNotifications

Admin queries and mutations

  • getAllSubscribers: Paginated subscriber list with search/filter
  • deleteSubscriber: Remove subscriber from database
  • getNewsletterStats: Stats for admin dashboard
  • getPostsForNewsletter: List of posts with sent status

Updated files: convex/newsletter.ts, convex/newsletterActions.ts, convex/posts.ts, convex/crons.ts, src/config/siteConfig.ts, src/App.tsx, src/styles/global.css, src/pages/NewsletterAdmin.tsx

v1.36.0

Released December 27, 2025

Social footer component

  • Social footer component with customizable social links and copyright
    • Displays social icons on the left (GitHub, Twitter/X, LinkedIn, and more)
    • Shows copyright symbol, site name, and auto-updating year on the right
    • Configurable via siteConfig.socialFooter in src/config/siteConfig.ts
    • Supports 8 platform types: github, twitter, linkedin, instagram, youtube, tiktok, discord, website
    • Uses Phosphor icons for consistent styling
    • Appears below the main footer on homepage, blog posts, and pages
    • Can work independently of the main footer when set via frontmatter

Frontmatter control for social footer

  • showSocialFooter field for posts and pages to override siteConfig defaults
  • Set showSocialFooter: false to hide on specific posts/pages
  • Works like existing showFooter field pattern

Social footer configuration options

  • enabled: Global toggle for social footer
  • showOnHomepage, showOnPosts, showOnPages, showOnBlogPage: Per-location visibility
  • socialLinks: Array of social link objects with platform and URL
  • copyright.siteName: Site/company name for copyright display
  • copyright.showYear: Toggle for auto-updating year

Updated files: src/config/siteConfig.ts, convex/schema.ts, convex/posts.ts, convex/pages.ts, scripts/sync-posts.ts, src/pages/Home.tsx, src/pages/Post.tsx, src/pages/Blog.tsx, src/styles/global.css, src/components/SocialFooter.tsx

v1.35.0

Released December 26, 2025

Image support at top of posts and pages

  • showImageAtTop frontmatter field for posts and pages
    • Set showImageAtTop: true to display the image field at the top of the post/page above the header
    • Image displays full-width with rounded corners above the post header
    • Default behavior: if showImageAtTop is not set or false, image only used for Open Graph previews and featured card thumbnails
    • Works for both blog posts and static pages
    • Image appears above the post header when enabled

Updated files: convex/schema.ts, scripts/sync-posts.ts, convex/posts.ts, convex/pages.ts, src/pages/Post.tsx, src/pages/Write.tsx, src/styles/global.css

Documentation updated: content/pages/docs.md, content/blog/how-to-publish.md, content/blog/using-images-in-posts.md, files.md

v1.34.0

Released December 26, 2025

Blog page featured layout with hero post

  • blogFeatured frontmatter field for posts to mark as featured on blog page
    • First blogFeatured post displays as hero card with landscape image, tags, date, title, excerpt, author info, and read more link
    • Remaining blogFeatured posts display in 2-column featured row with excerpts
    • Regular (non-featured) posts display in 3-column grid without excerpts
    • New BlogHeroCard component (src/components/BlogHeroCard.tsx) for hero display
    • New getBlogFeaturedPosts query returns all published posts with blogFeatured: true sorted by date
    • PostList component updated with columns prop (2 or 3) and showExcerpts prop
    • Card images use 16:10 landscape aspect ratio
    • Footer support on blog page via siteConfig.footer.showOnBlogPage

Updated files: convex/schema.ts, convex/posts.ts, scripts/sync-posts.ts, src/pages/Blog.tsx, src/components/PostList.tsx, src/styles/global.css

v1.33.1

Released December 26, 2025

Article centering in sidebar layouts

  • Article content now centers in the middle column when sidebars are present
    • Left sidebar stays flush left, right sidebar stays flush right
    • Article uses margin-left: auto; margin-right: auto within its 1fr grid column
    • Works with both two-column (left sidebar only) and three-column (both sidebars) layouts
    • Consistent max-width: 800px for article content across all sidebar configurations

Updated files: src/styles/global.css

v1.33.0

Released December 26, 2025

AI Chat Write Agent (Agent) integration

  • AI Agent chat interface powered by Anthropic Claude API
    • New AIChatView component for AI-powered chat interface
    • Available on Write page (replaces textarea when enabled) and optionally in RightSidebar on posts/pages
    • Per-session, per-context chat history stored in Convex (aiChats table)
    • Supports page content as context for AI responses
    • Markdown rendering for AI responses with copy functionality
    • Theme-aware styling matching the site's design system
    • Uses Phosphor Icons for all UI elements
  • Convex backend for AI chat
    • New convex/aiChats.ts with queries and mutations for chat history
    • New convex/aiChatActions.ts with Claude API integration (requires ANTHROPIC_API_KEY environment variable)
    • System prompt configurable via Convex environment variables:
      • CLAUDE_PROMPT_STYLE, CLAUDE_PROMPT_COMMUNITY, CLAUDE_PROMPT_RULES (split prompts, joined with separators)
      • CLAUDE_SYSTEM_PROMPT (single prompt, fallback if split prompts not set)
    • Chat history limited to last 20 messages for context efficiency
    • Error handling: displays "API key is not set" message when ANTHROPIC_API_KEY is missing in Convex environment variables
  • Configuration options
    • siteConfig.aiChat interface with enabledOnWritePage and enabledOnContent boolean flags
    • Both flags default to false (opt-in feature)
    • New aiChat frontmatter field for posts and pages (requires rightSidebar: true)
  • Write page AI Agent mode
    • Title changes from "Blog Post" or "Page" to "Agent" when in AI chat mode
    • Toggle button text changes between "Agent" and "Text Editor"
    • Page scroll prevention when switching modes (no page jump)
  • RightSidebar AI chat support
    • Conditionally renders AIChatView when enabled via frontmatter aiChat: true field
    • Requires both siteConfig.aiChat.enabledOnContent and frontmatter aiChat: true
    • Passes page content as context for AI responses

Updated files: src/components/AIChatView.tsx, src/components/RightSidebar.tsx, src/pages/Write.tsx, src/pages/Post.tsx, src/config/siteConfig.ts, convex/schema.ts, convex/aiChats.ts, convex/aiChatActions.ts, convex/posts.ts, convex/pages.ts, scripts/sync-posts.ts, src/styles/global.css, package.json

Documentation updated: files.md, changelog.md, README.md, content/blog/setup-guide.md, public/raw/docs.md

v1.32.0

Released December 25, 2025

Custom homepage configuration

  • Set any page or blog post to serve as the homepage instead of the default Home component
  • Configure via siteConfig.homepage with type ("default", "page", or "post"), slug (required for page/post), and originalHomeRoute (default: "/home")
  • Custom homepage retains all Post component features (sidebar, copy dropdown, author info, footer) but without the featured section
  • Original homepage remains accessible at /home route (or configured originalHomeRoute) when custom homepage is set
  • SEO metadata uses the page/post's frontmatter when used as homepage
  • Back button hidden when Post component is used as homepage
  • Fork configuration support for homepage
    • Added homepage field to fork-config.json.example
    • Updated configure-fork.ts to handle homepage configuration
    • Documentation added to FORK_CONFIG.md with usage examples

Updated files: src/App.tsx, src/pages/Post.tsx, src/config/siteConfig.ts, scripts/configure-fork.ts, fork-config.json.example, FORK_CONFIG.md

v1.31.1

Released December 25, 2025

Image support in footer component

  • Footer markdown now supports images using standard markdown syntax or HTML
  • Images can be sized using width, height, style, or class HTML attributes
  • Image attributes are sanitized by rehypeSanitize for security (removes dangerous CSS)
  • Footer images support lazy loading and optional captions from alt text
  • CSS styles added for footer images

Updated files: src/components/Footer.tsx, src/styles/global.css

v1.31.0

Released December 25, 2025

Customizable footer component with markdown support

  • New Footer component that renders markdown content
  • Footer content can be set in frontmatter footer field (markdown) or use siteConfig.footer.defaultContent
  • Footer can be enabled/disabled globally via siteConfig.footer.enabled
  • Footer visibility controlled per-page type via siteConfig.footer.showOnHomepage, showOnPosts, showOnPages
  • New showFooter frontmatter field for posts and pages to override siteConfig defaults
  • New footer frontmatter field for posts and pages to provide custom markdown content
  • Footer renders inside article at bottom for posts/pages, maintains current position on homepage
  • Footer supports markdown formatting (links, paragraphs, line breaks)
  • Sidebars flush to bottom when footer is enabled

Updated files: src/components/Footer.tsx, src/pages/Home.tsx, src/pages/Post.tsx, src/config/siteConfig.ts, src/styles/global.css, convex/schema.ts, convex/posts.ts, convex/pages.ts, scripts/sync-posts.ts, src/pages/Write.tsx

Documentation updated: files.md, changelog.md

v1.30.2

Released December 25, 2025

Right sidebar default behavior fix

  • Right sidebar no longer appears on pages/posts without explicit rightSidebar: true in frontmatter
    • Changed default behavior: right sidebar is now opt-in only
    • Pages like About and Contact now render without the right sidebar as expected
    • CopyPageDropdown correctly appears in nav bar when right sidebar is disabled
  • Logic in Post.tsx changed from (page.rightSidebar ?? true) to page.rightSidebar === true

Updated files: src/pages/Post.tsx

v1.30.1

Released December 25, 2025

TypeScript error fix

  • TypeScript error in convex/posts.ts where rightSidebar was used in mutation handlers but missing from args validators
    • Added rightSidebar: v.optional(v.boolean()) to syncPosts args validator
    • Added rightSidebar: v.optional(v.boolean()) to syncPostsPublic args validator

Updated files: convex/posts.ts

v1.30.0

Released December 25, 2025

Right sidebar feature for posts and pages

  • New RightSidebar component that displays CopyPageDropdown in a right sidebar
    • Appears at 1135px+ viewport width when enabled
    • Controlled by siteConfig.rightSidebar.enabled (global toggle)
    • Per-post/page control via rightSidebar: true frontmatter field (opt-in only)
    • Three-column layout support: left sidebar (TOC), main content, right sidebar (CopyPageDropdown)
    • CopyPageDropdown automatically moves from nav to right sidebar when enabled
    • Responsive: right sidebar hidden below 1135px, CopyPageDropdown returns to nav
  • Right sidebar configuration in siteConfig
    • rightSidebar.enabled: Global toggle for right sidebar feature
    • rightSidebar.minWidth: Minimum viewport width to show sidebar (default: 1135px)
  • rightSidebar frontmatter field
    • Available for both blog posts and pages
    • Optional boolean field to enable/disable right sidebar per post/page
    • Added to Write page frontmatter reference with copy button

Updated files: src/components/RightSidebar.tsx, src/pages/Post.tsx, src/config/siteConfig.ts, src/styles/global.css, convex/schema.ts, convex/posts.ts, convex/pages.ts, scripts/sync-posts.ts, src/pages/Write.tsx

Documentation updated: content/blog/setup-guide.md, content/pages/docs.md, files.md, changelog.md

v1.29.0

Released December 25, 2025

Font family configuration system

  • Font family configuration via siteConfig.ts
    • Three font options: "serif" (New York), "sans" (system fonts), "monospace" (IBM Plex Mono)
    • Configure default font in src/config/siteConfig.ts with fontFamily option
    • Font preference persists in localStorage across page reloads
    • SiteConfig default font overrides localStorage when siteConfig changes
  • Monospace font option added
    • Added monospace to FONT SWITCHER options in global.css
    • Uses "IBM Plex Mono", "Liberation Mono", ui-monospace, monospace
    • Write page font switcher now cycles through all three options
  • Fork configuration support
    • Added fontFamily field to fork-config.json.example
    • Automated fork configuration script supports fontFamily option

Updated files: src/config/siteConfig.ts, src/context/FontContext.tsx, src/main.tsx, src/pages/Write.tsx, src/styles/global.css, scripts/configure-fork.ts, fork-config.json.example

Documentation updated: content/blog/setup-guide.md, content/pages/docs.md, files.md

v1.28.2

Released December 25, 2025

Plain text code block wrapping

  • Code blocks without a language specifier now wrap text properly
  • Fixed horizontal overflow for long error messages and prose in code blocks
  • Updated inline vs block code detection logic
    • Inline code: short content (< 80 chars), no newlines, no language class
    • Block code: longer content or has language specifier
  • Text wrapping uses pre-wrap styling applied via SyntaxHighlighter props

Updated files: src/components/BlogPost.tsx, src/styles/global.css

v1.28.1

Released December 25, 2025

RSS feed validation fixes

  • Standardized all URLs to www.markdown.fast across the application
  • Fixed atom:link rel="self" attribute mismatch that caused RSS validation failures
  • Updated index.html meta tags (og:url, og:image, twitter:domain, twitter:url, twitter:image, JSON-LD)
  • Updated convex/rss.ts and convex/http.ts SITE_URL constants to use www.markdown.fast
  • Updated public/robots.txt, public/openapi.yaml, and public/llms.txt with www URLs
  • RSS exclusions already present in netlify.toml for botMeta edge function

All URL references now consistently use https://www.markdown.fast. RSS feed rel="self" attribute now matches actual feed URL. Build passes successfully.

v1.28.0

Released December 25, 2025

Discovery files sync automation

  • New discovery files sync script
    • Automatically updates AGENTS.md and llms.txt with current app data
    • Reads from siteConfig.ts and queries Convex for post/page counts
    • Preserves existing AGENTS.md instructional content
    • Regenerates llms.txt with current site information
  • New npm sync commands
    • npm run sync:discovery - Update discovery files (development)
    • npm run sync:discovery:prod - Update discovery files (production)
    • npm run sync:all - Sync content + discovery files together (development)
    • npm run sync:all:prod - Sync content + discovery files together (production)
  • Fork configuration support for gitHubRepo
    • Added gitHubRepoConfig to fork-config.json.example
    • Updated configure-fork.ts with backward compatibility for legacy fields

Updated files: scripts/sync-discovery-files.ts, package.json, fork-config.json.example, scripts/configure-fork.ts, FORK_CONFIG.md, files.md

Documentation updated: README.md, docs.md, setup-guide.md, about.md, about-this-blog.md

v1.27.0

Released December 24, 2025

Homepage post limit and optional read more link

  • Configurable post limit for homepage via siteConfig.postsDisplay.homePostsLimit
    • Default limit set to 10 most recent posts
    • Set to undefined to show all posts (no limit)
  • Optional "read more" link below limited post list
    • Configurable via siteConfig.postsDisplay.homePostsReadMore
    • Customizable link text and destination URL
    • Only appears when posts are limited and there are more posts than the limit
    • Default links to /blog page
    • Can be disabled by setting enabled: false

Updated files: src/config/siteConfig.ts, src/pages/Home.tsx, src/styles/global.css

v1.26.0

Released December 24, 2025

Tag pages, related posts, and AI service links re-enabled

  • Tag pages at /tags/[tag] route
    • Dynamic tag archive pages showing all posts with a specific tag
    • View mode toggle (list/cards) with localStorage persistence
    • Mobile responsive layout matching existing blog page design
    • Sitemap updated to include all tag pages dynamically
  • Related posts component for blog post footers
    • Shows up to 3 related posts based on shared tags
    • Sorted by relevance (number of shared tags) then by date
    • Only displays on blog posts (not static pages)
  • Improved tag links in post footers
    • Tags now link to /tags/[tag] archive pages
    • Visual styling consistent with existing theme
  • Open in AI service links re-enabled in CopyPageDropdown
    • Uses GitHub raw URLs instead of Netlify paths (bypasses edge function issues)
    • ChatGPT, Claude, and Perplexity links with universal prompt
    • "Requires git push" hint for users (npm sync alone doesn't update GitHub)
    • Visual divider separating AI options from other menu items

Updated files: src/config/siteConfig.ts, convex/schema.ts, convex/posts.ts, convex/http.ts, src/pages/TagPage.tsx, src/pages/Post.tsx, src/components/CopyPageDropdown.tsx, src/styles/global.css, src/App.tsx

Documentation updated: content/pages/docs.md, content/blog/setup-guide.md

v1.25.2

Released December 24, 2025

AI service links disabled due to Netlify edge function issues

  • Direct links to ChatGPT, Claude, and Perplexity removed from CopyPageDropdown

    • AI crawlers cannot reliably fetch /raw/*.md files despite multiple configuration attempts
    • Netlify edge functions intercept requests before static files are served
    • Multiple solutions attempted: excludedPath, code-level bypasses, AI crawler whitelisting, Netlify Functions, header adjustments
    • None resolved the issue for ChatGPT or Perplexity (Claude works)
  • Workaround for users

    • Copy page: copies markdown to clipboard, paste directly into any AI tool
    • View as Markdown: opens raw .md file in browser for manual copying
    • Download as SKILL.md: downloads in Anthropic Agent Skills format
  • Removed Netlify Function at /api/raw/:slug

    • Caused build failures and dependency conflicts
    • Static /raw/*.md files still work in browsers

Updated files: src/components/CopyPageDropdown.tsx, netlify.toml

Documentation: content/blog/netlify-edge-excludedpath-ai-crawlers.md updated with detailed log of all attempted solutions

v1.25.1

Released December 24, 2025

Logo moved to top navigation header

  • Logo now appears in header bar (top-left) on all pages
  • Separate from back button and navigation links
  • Reads from siteConfig.innerPageLogo and siteConfig.logo
  • Mobile responsive: logo positioned on left in header

Updated files: src/components/Layout.tsx, src/pages/Post.tsx, src/pages/Blog.tsx, src/styles/global.css

v1.25.0

Released December 24, 2025

Sidebar styling updated to match Cursor docs style

  • Sidebar has alternate background color for visual separation
  • Vertical border line on right side of sidebar
  • Theme-aware colors for all four themes
  • Sidebar width increased to 240px
  • Mobile responsive: sidebar hidden below 1024px

Updated files: src/styles/global.css

v1.24.4

Released December 23, 2025

Navigation visibility control and hardcoded nav items

  • showInNav field for pages to control navigation visibility

    • Pages can be published and accessible but hidden from navigation menu
    • Set showInNav: false in page frontmatter to hide from nav
    • Defaults to true for backwards compatibility (all existing pages show in nav)
    • Pages with showInNav: false remain:
      • Published and accessible via direct URL
      • Searchable via search indexes
      • Available via API endpoints
      • Just hidden from the navigation menu
    • Matches the pattern used for blogPage.showInNav in siteConfig.ts
  • Hardcoded navigation items configuration for React routes

    • Add React route pages (like /stats, /write) to navigation via siteConfig.hardcodedNavItems
    • Configure navigation order, title, and visibility per route
    • Set showInNav: false to hide from nav while keeping route accessible
    • Navigation combines Blog link, hardcoded nav items, and markdown pages
    • All nav items sorted by order field (lower = first)

Example configuration:

// src/config/siteConfig.ts
hardcodedNavItems: [
  {
    slug: "stats",
    title: "Stats",
    order: 10,
    showInNav: true,
  },
  {
    slug: "write",
    title: "Write",
    order: 20,
    showInNav: true,
  },
],

Updated files: convex/schema.ts, convex/pages.ts, scripts/sync-posts.ts, src/pages/Write.tsx, src/config/siteConfig.ts, src/components/Layout.tsx

Documentation updated: content/pages/docs.md, content/blog/setup-guide.md

v1.24.3

Released December 23, 2025

Inner page logo configuration

  • Logo displays in header on blog page, individual posts, and static pages
  • Desktop: logo positioned on the left (before back button)
  • Mobile: logo positioned on the right (smaller size for compact header)
  • Configurable via siteConfig.innerPageLogo.enabled and siteConfig.innerPageLogo.size
  • Does not affect homepage logo (controlled separately)
  • Logo links to homepage when clicked

Configuration:

// src/config/siteConfig.ts
innerPageLogo: {
  enabled: true,  // Set to false to hide logo on inner pages
  size: 28,      // Logo height in pixels (keeps aspect ratio)
},

Updated files: src/config/siteConfig.ts, src/pages/Blog.tsx, src/pages/Post.tsx, src/styles/global.css

v1.24.2

Released December 23, 2025

Mobile menu redesign with sidebar integration

  • Mobile navigation controls moved to left side

    • Hamburger menu, search, and theme toggle now positioned on the left
    • Order: hamburger first, then search, then theme toggle
    • Consistent left-aligned navigation on mobile devices
  • Sidebar table of contents in mobile menu

    • When a page or blog post has sidebar layout, the TOC appears in the mobile menu
    • Desktop sidebar hidden on mobile (max-width: 768px) since accessible via hamburger
    • Back button and CopyPageDropdown remain visible above main content on mobile
    • Sidebar headings displayed with same collapsible tree structure as desktop
  • Typography standardization

    • All mobile menu elements use CSS variables for font sizes
    • Font-family standardized using inherit to match body font
    • Mobile menu TOC links use consistent sizing with desktop sidebar
    • Added CSS variables: --font-size-mobile-toc-title and --font-size-mobile-toc-link

New files: src/context/SidebarContext.tsx

Updated files: src/components/Layout.tsx, src/components/MobileMenu.tsx, src/pages/Post.tsx, src/styles/global.css

v1.24.1

Released December 23, 2025

Sidebar navigation fixes

  • Fixed anchor link navigation when sidebar sections are collapsed or expanded

    • Navigation now correctly scrolls to target headings with proper header offset
    • Sections expand automatically when navigating to nested headings
    • Collapse button works reliably without triggering navigation
    • Manual collapse/expand state persists during scrolling
  • Fixed heading extraction to ignore code blocks

    • Sidebar no longer shows example headings from markdown code examples
    • Only actual page headings appear in the table of contents
    • Filters out fenced code blocks (```) and indented code blocks

Updated files: src/components/PageSidebar.tsx, src/utils/extractHeadings.ts

v1.24.0

Released December 23, 2025

Sidebar layout for blog posts

  • Blog posts now support layout: "sidebar" frontmatter field
  • Previously only available for static pages, now works for posts too
  • Enables docs-style layout with table of contents sidebar for long-form content
  • Same features as page sidebar: automatic TOC extraction, active heading highlighting, smooth scroll navigation
  • Mobile responsive: stacks to single column below 1024px

Add layout: "sidebar" to any blog post frontmatter to enable the sidebar layout. The sidebar extracts headings (H1, H2, H3) automatically and only appears if headings exist in the content.

Example:

---
title: "My Tutorial"
description: "A detailed guide"
date: "2025-01-20"
slug: "my-tutorial"
published: true
tags: ["tutorial"]
layout: "sidebar"
---

Updated files: convex/schema.ts, scripts/sync-posts.ts, convex/posts.ts, src/pages/Post.tsx, src/pages/Write.tsx

Documentation updated: docs.md, setup-guide.md, how-to-publish.md

v1.23.0

Released December 23, 2025

Collapsible sections in markdown

  • Create expandable/collapsible content using HTML <details> and <summary> tags
  • Use <details open> attribute for sections that start expanded by default
  • Supports nested collapsible sections for multi-level content
  • Theme-aware styling for all four themes (dark, light, tan, cloud)
  • Works with all markdown content inside: lists, code blocks, bold, italic, links, etc.

Example usage:

<details>
  <summary>Click to expand</summary>

  Hidden content here with **markdown** support.
</details>

New packages: rehype-raw, rehype-sanitize

Updated files: src/components/BlogPost.tsx, src/styles/global.css

Documentation updated: markdown-with-code-examples.md, docs.md

v1.22.0

Released December 21, 2025

Sidebar layout for pages

  • Pages can now use a docs-style layout with table of contents sidebar
  • Add layout: "sidebar" to page frontmatter to enable
  • Left sidebar displays TOC extracted from H1, H2, H3 headings automatically
  • Two-column grid layout: 220px sidebar + flexible content area
  • Active heading highlighting on scroll
  • Smooth scroll navigation to sections
  • Sidebar only appears if headings exist in content
  • Mobile responsive: stacks to single column below 1024px
  • CopyPageDropdown remains in top navigation for sidebar pages

New files: src/utils/extractHeadings.ts, src/components/PageSidebar.tsx

Updated files: convex/schema.ts, scripts/sync-posts.ts, convex/pages.ts, src/pages/Post.tsx, src/styles/global.css

v1.21.0

Released December 21, 2025

Blog page view mode toggle

  • Blog page now supports two view modes: list view and card view
  • Toggle button in blog header switches between views
  • List view: year-grouped posts with titles, read time, and dates
  • Card view: 3-column grid with thumbnails, titles, excerpts, and metadata
  • Default view configurable via siteConfig.blogPage.viewMode
  • Toggle visibility controlled by siteConfig.blogPage.showViewToggle
  • View preference saved to localStorage and persists across visits
  • Responsive grid: 3 columns (desktop), 2 columns (tablet), 1 column (mobile)
  • Theme-aware styling for all four themes (dark, light, tan, cloud)
  • Cards display post thumbnails from image frontmatter field
  • Posts without images show cards without thumbnail areas

Updated files: src/pages/Blog.tsx, src/components/PostList.tsx, src/config/siteConfig.ts, src/styles/global.css

v1.20.3

Released December 21, 2025

SEO, AEO, and GEO improvements

  • Raw markdown files now accessible to AI crawlers (ChatGPT, Perplexity)
  • Added /raw/ path bypass in botMeta edge function so AI services receive markdown, not HTML
  • Sitemap now includes static pages (about, docs, contact, etc.)
  • Security headers: X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy
  • Link header pointing to llms.txt for AI discovery
  • Raw markdown files served with proper Content-Type and CORS headers
  • Preconnect hints for Convex backend (faster API calls)
  • Fixed URL consistency: openapi.yaml and robots.txt now use www.markdown.fast

v1.20.2

Released December 21, 2025

Write conflict prevention for heartbeat mutation

  • Increased backend dedup window from 10s to 20s
  • Increased frontend debounce from 10s to 20s to match backend
  • Added random jitter (±5s) to heartbeat intervals to prevent synchronized calls across tabs
  • Simplified early return to skip ANY update within dedup window
  • Prevents "Documents read from or written to the activeSessions table changed" errors

v1.20.1

Released December 21, 2025

Visitor map styling improvements

  • Removed box-shadow from map wrapper for cleaner flat design
  • Increased land dot contrast for better globe visibility on all themes
  • Increased land dot opacity from 0.6 to 0.85
  • Darker/more visible land colors for light, tan, and cloud themes
  • Lighter land color for dark theme to stand out on dark background

v1.20.0

Released December 21, 2025

Real-time visitor map on stats page

  • Displays live visitor locations on a dotted world map
  • Uses Netlify's built-in geo detection via edge function (no third-party API needed)
  • Privacy friendly: stores city, country, and coordinates only (no IP addresses)
  • Theme-aware colors for all four themes (dark, light, tan, cloud)
  • Animated pulsing dots for active visitors
  • Configurable via siteConfig.visitorMap

New files:

  • netlify/edge-functions/geo.ts: Edge function returning geo data from Netlify headers
  • src/components/VisitorMap.tsx: SVG world map component with visitor dots

Configuration:

// src/config/siteConfig.ts
visitorMap: {
  enabled: true,        // Set to false to hide
  title: "Live Visitors", // Optional title above the map
},

Updated files: convex/schema.ts, convex/stats.ts, src/hooks/usePageTracking.ts, src/pages/Stats.tsx, src/config/siteConfig.ts, src/styles/global.css

Documentation updated: setup-guide.md, docs.md, FORK_CONFIG.md, fork-config.json.example, fork-configuration-guide.md

v1.19.2

Released December 21, 2025

Improved AI service prompts in CopyPageDropdown

  • Updated ChatGPT, Claude, and Perplexity prompts with clearer instructions
  • AI now attempts to load raw markdown URL and provides fallback behavior
  • If content loads: provides concise summary and asks how to help
  • If content fails: states page could not be loaded without guessing content

Updated file: src/components/CopyPageDropdown.tsx

v1.19.1

Released December 21, 2025

GitHub Stars on Stats page

  • New GitHub Stars card displays live star count from repository
  • Fetches from GitHub public API (no token required)
  • Uses Phosphor GithubLogo icon
  • Stats page now shows 6 cards in a single row
  • Responsive layout: 3x2 on tablet, 2x3 on mobile, stacked on small screens

Updated files: src/pages/Stats.tsx, src/styles/global.css

v1.19.0

Released December 21, 2025

Author display for posts and pages

  • New optional authorName and authorImage frontmatter fields
  • Round avatar image displayed next to date and read time
  • Works on individual post and page views (not on blog list)
  • Write page updated with new frontmatter field reference

Example frontmatter:

authorName: "Your Name"
authorImage: "/images/authors/photo.png"

Place author avatar images in public/images/authors/. Recommended: square images (they display as circles).

Updated files: convex/schema.ts, scripts/sync-posts.ts, convex/posts.ts, convex/pages.ts, src/pages/Post.tsx, src/pages/Write.tsx, src/styles/global.css

Documentation updated: setup-guide.md, docs.md, files.md, README.md, AGENTS.md

New PRD: prds/howto-Frontmatter.md with reusable prompt for future frontmatter updates.

v1.18.1

Released December 21, 2025

CopyPageDropdown raw markdown URLs

  • AI services (ChatGPT, Claude, Perplexity) now receive raw markdown file URLs instead of page URLs
  • URL format: /raw/{slug}.md (e.g., /raw/setup-guide.md)
  • AI services can fetch and parse clean markdown content directly
  • Includes metadata headers for structured parsing
  • No HTML parsing required by AI services

v1.18.0

Released December 20, 2025

Automated fork configuration

  • New npm run configure command for one-step fork setup
  • Copy fork-config.json.example to fork-config.json
  • Edit the JSON file with your site information
  • Run npm run configure to apply all changes automatically

Two options for fork setup:

  1. Automated (recommended): JSON config file + npm run configure
  2. Manual: Follow step-by-step instructions in FORK_CONFIG.md

The configure script updates all 11 configuration files:

File What it updates
src/config/siteConfig.ts Site name, bio, GitHub, features
src/pages/Home.tsx Intro paragraph, footer links
src/pages/Post.tsx SITE_URL, SITE_NAME constants
convex/http.ts SITE_URL, SITE_NAME constants
convex/rss.ts SITE_URL, SITE_TITLE, SITE_DESCRIPTION
index.html Meta tags, JSON-LD, page title
public/llms.txt Site info, GitHub link
public/robots.txt Sitemap URL
public/openapi.yaml Server URL, site name
public/.well-known/ai-plugin.json Plugin metadata
src/context/ThemeContext.tsx Default theme

New files: FORK_CONFIG.md, fork-config.json.example, scripts/configure-fork.ts

v1.17.0

Released December 20, 2025

GitHub contributions graph

  • GitHub activity graph on homepage with theme-aware colors
  • Year navigation with Phosphor CaretLeft/CaretRight icons
  • Click graph to visit GitHub profile
  • Configurable via siteConfig.gitHubContributions
  • Uses public API (no GitHub token required)

Theme-specific contribution colors:

  • Dark theme: GitHub green on dark background
  • Light theme: Standard GitHub green
  • Tan theme: Warm brown tones
  • Cloud theme: Gray-blue tones

New component: src/components/GitHubContributions.tsx

Set enabled: false in siteConfig to disable.

v1.15.2

Released December 20, 2025

Write page font switcher

  • Font switcher in /write page Actions section
  • Toggle between Serif and Sans-serif fonts in the writing area
  • Font preference saved to localStorage and persists across sessions
  • Uses same font families defined in global.css

v1.15.1

Released December 20, 2025

Write page theme and content fixes

  • Fixed theme toggle icons on /write page to match ThemeToggle.tsx (Moon, Sun, Half2Icon, Cloud)
  • Content type switching now always updates the template in the writing area

v1.15.0

Released December 20, 2025

Write page three-column layout

  • Redesigned /write page with Cursor docs-style three-column layout
  • Left sidebar: content type selector (Blog Post/Page) and action buttons (Clear, Theme)
  • Center: full-screen writing area with Copy All button
  • Right sidebar: frontmatter field reference with individual copy buttons for each field
  • Warning message about refresh losing content
  • Stats bar showing words, lines, and characters

v1.14.0

Released December 20, 2025

Write page Notion-like UI

  • Redesigned /write page with full-screen, distraction-free writing experience
  • Floating header with home link, type selector, and action buttons
  • Collapsible frontmatter panel on the right
  • Removed borders from writing area for cleaner look
  • Improved typography and spacing

v1.13.0

Released December 20, 2025

Markdown write page

  • New /write page for drafting markdown content (not linked in navigation)
  • Content type selector for Blog Post or Page with appropriate frontmatter templates
  • Frontmatter reference with copy buttons for each field
  • Theme toggle matching site themes
  • Word, line, and character counts
  • localStorage persistence for content, type, and font preference
  • Works with Grammarly and browser spellcheck
  • Copy all button for easy content transfer
  • Clear button to reset content

Access at yourdomain.com/write. Content stored in localStorage only.

v1.12.2

Released December 20, 2025

Centralized font-size CSS variables

  • All font sizes now use CSS variables for easier customization
  • Base scale from --font-size-3xs (10px) to --font-size-hero (64px)
  • Component-specific variables for blog headings, navigation, search, stats, and more
  • Mobile responsive overrides at 768px breakpoint

Edit src/styles/global.css to customize font sizes across the entire site by changing the :root variables.

v1.12.1

Released December 20, 2025

Open Graph image fix

  • Posts with image in frontmatter now display their specific OG image when shared
  • Posts without images fall back to og-default.svg
  • Pages now supported with og:type set to "website" instead of "article"
  • Relative image paths (like /images/v17.png) resolve to absolute URLs

The /meta/post endpoint in convex/http.ts now passes the image field from posts and pages to the meta HTML generator. If no post matches the slug, it checks for a page with that slug.

v1.12.0

Released December 20, 2025

Dedicated blog page with configurable navigation

  • New /blog page for dedicated post listing
  • Enable/disable via siteConfig.blogPage.enabled
  • Control navigation position with siteConfig.blogPage.order
  • Centralized site configuration in src/config/siteConfig.ts
  • Flexible post display: homepage only, blog page only, or both

Configuration options:

// src/config/siteConfig.ts
blogPage: {
  enabled: true,         // Enable /blog route
  showInNav: true,       // Show in navigation
  title: "Blog",         // Page title
  order: 0,              // Nav order (lower = first)
},
displayOnHomepage: true, // Show posts on homepage

The Blog link now integrates with page navigation ordering. Set order: 5 to place it after pages with order 0-4, or order: 0 to keep it first.

New files: src/config/siteConfig.ts, src/pages/Blog.tsx

v1.11.1

Released December 20, 2025

Fix historical stats display and chunked backfilling

  • Stats page now shows all historical page views correctly
  • Changed getStats to use direct counting until aggregates are fully backfilled
  • Backfill mutation now processes 500 records at a time (chunked)
  • Prevents memory limit issues with large datasets (16MB Convex limit)
  • Schedules itself to continue processing until complete

v1.11.0

Released December 20, 2025

Aggregate component for efficient stats

  • Replaced O(n) table scans with O(log n) aggregate counts
  • Uses @convex-dev/aggregate package for TableAggregate
  • Three aggregates: totalPageViews, pageViewsByPath, uniqueVisitors
  • Backfill mutation for existing page view data
  • Updated convex/convex.config.ts with aggregate component registration
  • Updated convex/stats.ts to use aggregate counts in getStats query
  • Updated prds/howstatsworks.md with old vs new implementation comparison

Performance improvement: Stats queries now use pre-computed counts instead of scanning all page view records.

v1.10.0

Released December 20, 2025

Fork configuration documentation

  • Added "Files to Update When Forking" section to docs and setup guide
  • Lists all 9 configuration files users need to update when forking
  • Includes backend configuration examples for Convex files
  • Code snippets for convex/http.ts, convex/rss.ts, src/pages/Post.tsx

Site branding updates

  • Updated public/robots.txt with sitemap URL and header
  • Updated public/llms.txt with site name and description
  • Updated public/.well-known/ai-plugin.json for AI plugins
  • Updated public/openapi.yaml API title and site name
  • Updated convex/http.ts SITE_URL and SITE_NAME constants

Same fork documentation added to README.md for discoverability.

v1.9.0

Released December 20, 2025

Scroll-to-top button

  • Appears after scrolling 300px (configurable)
  • Uses Phosphor ArrowUp icon for consistency
  • Smooth scroll animation (configurable)
  • Works with all four themes (dark, light, tan, cloud)
  • Enabled by default (can be disabled in Layout.tsx)
  • Fade-in animation when appearing
  • Responsive sizing for mobile devices

New component: src/components/ScrollToTop.tsx

Configuration via ScrollToTopConfig interface in src/components/Layout.tsx. Uses passive scroll listener for performance.

v1.8.0

Released December 20, 2025

Mobile menu and Generate Skill feature

  • Mobile menu with hamburger navigation
    • Slide-out drawer on mobile and tablet views
    • Accessible with keyboard navigation (Escape to close)
    • Focus trap for screen reader support
    • Page links and Home link in drawer
    • Auto-closes on route change
  • Generate Skill option in CopyPageDropdown
    • Formats post/page content as an AI agent skill file
    • Downloads as {slug}-skill.md with skill structure
    • Includes metadata, when to use, and instructions sections

New component: MobileMenu.tsx with HamburgerButton

v1.7.0

Released December 20, 2025

Raw markdown files and CopyPageDropdown improvements

  • Static raw markdown files at /raw/{slug}.md
    • Generated during npm run sync and npm run sync:prod in public/raw/ directory
    • Each published post and page gets a corresponding static .md file
    • Includes metadata header (type, date, reading time, tags)
  • View as Markdown option in CopyPageDropdown
    • Opens raw .md file in new tab
    • Available on all post and page views
  • Perplexity added to AI service options in CopyPageDropdown
    • Research articles directly in Perplexity with full content
  • Featured image support for posts and pages
    • image field displays as square thumbnail in card view
    • Non-square images automatically cropped to center
  • Improved markdown table CSS styling
    • GitHub-style tables with proper borders
    • Mobile responsive with horizontal scroll
    • Theme-aware alternating row colors

New files: public/raw/*.md (generated), updated _redirects

v1.6.1

Released December 18, 2025

Documentation updates

  • Added AGENTS.md with codebase instructions for AI coding agents
  • Added Firecrawl import to all "When to sync vs deploy" tables
  • Clarified import workflow: creates local files only, no import:prod needed
  • Updated docs: README, setup-guide, how-to-publish, docs page, about-this-blog
  • Renamed content/pages/changelog.md to changelog-page.md to avoid confusion with root changelog

v1.6.0

Released December 18, 2025

Content import and LLM API enhancements

  • Firecrawl content importer for external URLs
    • npm run import <url> scrapes and creates local markdown drafts
    • Creates drafts in content/blog/ with frontmatter
    • Then sync to dev (npm run sync) or prod (npm run sync:prod)
    • No separate import:prod command (import creates local files only)
  • New /api/export endpoint for batch content fetching
  • AI plugin discovery at /.well-known/ai-plugin.json
  • OpenAPI 3.0 specification at /openapi.yaml
  • Enhanced llms.txt with complete API documentation

New dependencies: @mendable/firecrawl-js

New files: scripts/import-url.ts, public/.well-known/ai-plugin.json, public/openapi.yaml

v1.5.0

Released December 17, 2025

Frontmatter-controlled featured items

  • Add featured: true to any post or page frontmatter
  • Use featuredOrder to control display order (lower = first)
  • Featured items sync instantly with npm run sync (no redeploy needed)

New Convex queries:

  • getFeaturedPosts: returns posts with featured: true
  • getFeaturedPages: returns pages with featured: true

Schema updates with featured and featuredOrder fields and by_featured index.

v1.4.0

Released December 17, 2025

Featured section with list/card view toggle

  • Card view displays title and excerpt in a responsive grid
  • Toggle button in featured header to switch between views
  • View preference saved to localStorage

Logo gallery with continuous marquee scroll

  • Clickable logos with configurable URLs
  • CSS only animation for smooth infinite scrolling
  • Configurable speed, position, and title
  • Grayscale logos with color on hover
  • Responsive sizing across breakpoints
  • 5 sample logos included

New frontmatter field

  • excerpt field for posts and pages
  • Used for card view descriptions
  • Falls back to description field for posts

v1.3.0

Released December 17, 2025

Real-time search with Command+K

  • Search icon in top nav using Phosphor Icons
  • Modal with keyboard navigation (arrow keys, Enter, Escape)
  • Full text search across posts and pages using Convex search indexes
  • Result snippets with context around search matches
  • Distinguishes between posts and pages with type badges

Search uses Convex full text search with reactive queries. Results deduplicate from title and content searches. Title matches sort first.

v1.2.0

Released December 15, 2025

Real-time stats page at /stats

  • Active visitors count with per-page breakdown
  • Total page views and unique visitors
  • Views by page sorted by popularity

Page view tracking via event records pattern (no write conflicts). Active session heartbeat system with 30s interval and 2min timeout. Cron job for stale session cleanup every 5 minutes.

New Convex tables: pageViews and activeSessions.

v1.1.0

Released December 14, 2025

Netlify Edge Functions for dynamic Convex HTTP proxying

  • rss.ts proxies /rss.xml and /rss-full.xml
  • sitemap.ts proxies /sitemap.xml
  • api.ts proxies /api/posts and /api/post

Vite dev server proxy for RSS, sitemap, and API endpoints. Edge functions dynamically read VITE_CONVEX_URL from environment.

v1.0.0

Released December 14, 2025

Initial release

  • Markdown posts with frontmatter parsing
  • Static pages support (About, Projects, Contact)
  • Four theme options: Dark, Light, Tan (default), Cloud
  • Syntax highlighting for code blocks
  • Year-grouped post list on home page
  • Individual post pages with share buttons

SEO and discovery

  • Dynamic sitemap at /sitemap.xml
  • JSON-LD structured data for blog posts
  • RSS feeds at /rss.xml and /rss-full.xml
  • AI agent discovery with llms.txt
  • robots.txt with rules for AI crawlers

API endpoints

  • /api/posts for JSON list of all posts
  • /api/post?slug=xxx for single post as JSON or markdown

Copy Page dropdown for sharing to ChatGPT and Claude.

Technical stack

  • React 18 with TypeScript
  • Convex for real-time database
  • react-markdown for rendering
  • react-syntax-highlighter for code blocks
  • Netlify deployment with edge functions