73 KiB
Changelog
Type: page Date: 2026-01-04
All notable changes to this project.
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: truein 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?.contentpattern
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
defaultThemefield 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
Themetype export tosrc/config/siteConfig.ts - Added
defaultTheme?: Themefield to SiteConfig interface - Updated
src/context/ThemeContext.tsxto import from siteConfig - Renamed
updateThemeContexttoupdateThemeConfiginscripts/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
docsSectionGroupIconfrontmatter 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.tswithdocsSectionGroupIconfield in posts and pages tables - Updated
convex/posts.tsandconvex/pages.tsqueries and mutations - Updated
scripts/sync-posts.tsto parsedocsSectionGroupIconfrom frontmatter - Updated
src/components/DocsSidebar.tsxwith Phosphor icon imports and rendering - Added CSS styles for
.docs-sidebar-group-icon - Updated
.claude/skills/frontmatter.mdwith 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
docsSectionGroupOrderfrontmatter field for controlling docs sidebar group order - Groups are sorted by the minimum
docsSectionGroupOrdervalue among items in each group - Lower numbers appear first, groups without this field sort alphabetically
- Works alongside
docsSection,docsSectionGroup, anddocsSectionOrderfields
Example usage:
---
docsSection: true
docsSectionGroup: "Getting Started"
docsSectionGroupOrder: 1
docsSectionOrder: 1
---
Technical details:
- Updated
convex/schema.tswithdocsSectionGroupOrderfield in posts and pages tables - Updated
convex/posts.tsandconvex/pages.tsqueries and mutations - Updated
scripts/sync-posts.tsto parsedocsSectionGroupOrderfrom frontmatter - Updated
src/components/DocsSidebar.tsxto sort groups bydocsSectionGroupOrder
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
aiDashboardconfiguration in siteConfigenableImageGeneration: Toggle image generation tabdefaultTextModel: Set default AI model for chattextModels: Configure available text chat modelsimageModels: Configure available image generation models
Technical details:
- New file:
convex/aiImageGeneration.tsfor Gemini image generation action - New table:
aiGeneratedImagesin schema for tracking generated images - Updated
convex/aiChatActions.tswith multi-provider support- Added
callAnthropicApi,callOpenAIApi,callGeminiApihelper functions - Added
getProviderFromModelto determine provider from model ID - Added
getApiKeyForProviderfor lazy API key retrieval - Added
getNotConfiguredMessagefor provider-specific setup instructions
- Added
- Updated
src/components/AIChatView.tsxwithselectedModelprop - Updated
src/pages/Dashboard.tsxwith 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-tabfor tab navigation.ai-model-selector,.ai-model-dropdownfor model selection.ai-aspect-ratio-selectorfor aspect ratio options.ai-generated-image,.ai-image-error,.ai-image-loadingfor image display
Environment Variables:
ANTHROPIC_API_KEY: Required for Claude modelsOPENAI_API_KEY: Required for GPT-4oGOOGLE_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
showInHeaderoption insiteConfig.socialFooterto 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: truein socialFooter config to enable
Technical details:
- Exported
platformIconsfromsrc/components/SocialFooter.tsxfor reuse - Added social icon rendering in
src/components/Layout.tsxheader controls - Added
.header-social-linksand.header-social-linkCSS styles - Updated
SocialFooterConfiginterface withshowInHeader: 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
sandboxandloading="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_DOMAINSconstant insrc/components/BlogPost.tsx - Added
iframeto sanitize schema with allowed attributes - Added custom iframe component handler with URL validation
- Added
.embed-containerCSS 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/:authorSlugdisplaying 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 countsgetPostsByAuthor: 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_authorNameindex to posts table inconvex/schema.ts - New queries in
convex/posts.ts:getAllAuthors,getPostsByAuthor - New component:
src/pages/AuthorPage.tsx(based on TagPage.tsx pattern) - Added route
/author/:authorSluginsrc/App.tsx - Updated
src/pages/Post.tsxto 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 definederror when runningnpm run configure - Added
fileURLToPathimport fromurlmodule 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.mdfor managing footer content via markdown sync- Footer content syncs with
npm run syncwithout redeploy needed - Edit footer text, links, and formatting through markdown instead of code
- Falls back to
siteConfig.footer.defaultContentwhen page not found - Set
showInNav: falseto hide from navigation (page remains accessible via direct URL) - Supports full markdown including links, paragraphs, and line breaks
- Footer content syncs with
Technical details:
- New file:
content/pages/footer.mdwith frontmatter (slug: "footer", showInNav: false) - Updated:
src/pages/Home.tsxto fetch footer page by slug "footer" - Updated:
src/pages/Blog.tsxto fetch footer page by slug "footer" - Footer component now prioritizes page content over siteConfig.defaultContent
- Pattern matches
home-intropage 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/directoryfrontmatter.md: Complete frontmatter syntax with all 25+ field options for posts and pagesconvex.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
- CLAUDE.md status comment updated during
- Unlisted posts feature
- New
unlistedfrontmatter field for blog posts - Set
unlisted: trueto 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
- New
Technical details:
- New file:
CLAUDE.mdin project root - New directory:
.claude/skills/with three markdown files - Updated:
scripts/sync-discovery-files.tsto update CLAUDE.md alongside AGENTS.md and llms.txt - Updated:
convex/schema.ts- Addedunlistedoptional 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- Addedunlistedto interfaces and parsing logic - Updated:
src/pages/Write.tsx- Addedunlistedto 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
recordPageViewmutation 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
ImageLightboxcomponent inBlogPost.tsxwith 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-serverto 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_TOKENenvironment 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-servercommand throughout dashboard
- Run
Technical details:
- New
scripts/sync-server.tsfile implements local HTTP server - Uses Node.js
child_process.spawnto 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
requireAuthisfalse, dashboard is open access - When
requireAuthistrueand WorkOS is configured, dashboard requires login - Shows setup instructions if
requireAuthistruebut 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
/dashboardprovides 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.tssettings, generates downloadable config file - Index HTML editor: View and edit
index.htmlcontent with meta tags, Open Graph, Twitter Cards, JSON-LD - Analytics: Real-time stats dashboard (clone of
/statspage, 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
StatsPageConfiginterface insiteConfig.tswithenabledandshowInNavoptions - 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.mdnow 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
- Accessible 24/7 at
- 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_KEYin Netlify environment variables - Add
Authorization: Bearer <key>header to requests
- Set
- Read-only access to blog content:
list_posts: Get all published posts with metadataget_post: Get single post by slug with full contentlist_pages: Get all published pagesget_page: Get single page by slug with full contentget_homepage: Get homepage data with featured and recent postssearch_content: Full text search across posts and pagesexport_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:sendnow callsscheduleSendPostNewslettermutation 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:statscommand- Sends weekly stats summary to your inbox on demand
- Uses
scheduleSendStatsSummarymutation - Email sent to AGENTMAIL_INBOX or AGENTMAIL_CONTACT_EMAIL
- New mutation
scheduleSendStatsSummaryinconvex/newsletter.ts- Allows CLI to trigger stats summary sending
- Schedules
sendWeeklyStatsSummaryinternal 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_EMAILorAGENTMAIL_INBOXas recipient - Configurable via
siteConfig.newsletterNotifications
Admin queries and mutations
getAllSubscribers: Paginated subscriber list with search/filterdeleteSubscriber: Remove subscriber from databasegetNewsletterStats: Stats for admin dashboardgetPostsForNewsletter: 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.socialFooterinsrc/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
showSocialFooterfield for posts and pages to override siteConfig defaults- Set
showSocialFooter: falseto hide on specific posts/pages - Works like existing
showFooterfield pattern
Social footer configuration options
enabled: Global toggle for social footershowOnHomepage,showOnPosts,showOnPages,showOnBlogPage: Per-location visibilitysocialLinks: Array of social link objects with platform and URLcopyright.siteName: Site/company name for copyright displaycopyright.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
showImageAtTopfrontmatter field for posts and pages- Set
showImageAtTop: trueto display theimagefield at the top of the post/page above the header - Image displays full-width with rounded corners above the post header
- Default behavior: if
showImageAtTopis not set orfalse, 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
- Set
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
blogFeaturedfrontmatter field for posts to mark as featured on blog page- First
blogFeaturedpost displays as hero card with landscape image, tags, date, title, excerpt, author info, and read more link - Remaining
blogFeaturedposts display in 2-column featured row with excerpts - Regular (non-featured) posts display in 3-column grid without excerpts
- New
BlogHeroCardcomponent (src/components/BlogHeroCard.tsx) for hero display - New
getBlogFeaturedPostsquery returns all published posts withblogFeatured: truesorted by date PostListcomponent updated withcolumnsprop (2 or 3) andshowExcerptsprop- Card images use 16:10 landscape aspect ratio
- Footer support on blog page via
siteConfig.footer.showOnBlogPage
- First
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: autowithin its1frgrid column - Works with both two-column (left sidebar only) and three-column (both sidebars) layouts
- Consistent
max-width: 800pxfor 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
AIChatViewcomponent 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
- New
- Convex backend for AI chat
- New
convex/aiChats.tswith queries and mutations for chat history - New
convex/aiChatActions.tswith 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
- New
- Configuration options
siteConfig.aiChatinterface withenabledOnWritePageandenabledOnContentboolean flags- Both flags default to false (opt-in feature)
- New
aiChatfrontmatter 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: truefield - Requires both
siteConfig.aiChat.enabledOnContentand frontmatteraiChat: true - Passes page content as context for AI responses
- Conditionally renders AIChatView when enabled via frontmatter
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.homepagewithtype("default", "page", or "post"),slug(required for page/post), andoriginalHomeRoute(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
/homeroute (or configuredoriginalHomeRoute) 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
homepagefield tofork-config.json.example - Updated
configure-fork.tsto handle homepage configuration - Documentation added to
FORK_CONFIG.mdwith usage examples
- Added
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, orclassHTML 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
Footercomponent that renders markdown content - Footer content can be set in frontmatter
footerfield (markdown) or usesiteConfig.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
showFooterfrontmatter field for posts and pages to override siteConfig defaults - New
footerfrontmatter 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: truein frontmatter- Changed default behavior: right sidebar is now opt-in only
- Pages like About and Contact now render without the right sidebar as expected
CopyPageDropdowncorrectly appears in nav bar when right sidebar is disabled
- Logic in
Post.tsxchanged from(page.rightSidebar ?? true)topage.rightSidebar === true
Updated files: src/pages/Post.tsx
v1.30.1
Released December 25, 2025
TypeScript error fix
- TypeScript error in
convex/posts.tswhererightSidebarwas used in mutation handlers but missing from args validators- Added
rightSidebar: v.optional(v.boolean())tosyncPostsargs validator - Added
rightSidebar: v.optional(v.boolean())tosyncPostsPublicargs validator
- Added
Updated files: convex/posts.ts
v1.30.0
Released December 25, 2025
Right sidebar feature for posts and pages
- New
RightSidebarcomponent that displaysCopyPageDropdownin a right sidebar- Appears at 1135px+ viewport width when enabled
- Controlled by
siteConfig.rightSidebar.enabled(global toggle) - Per-post/page control via
rightSidebar: truefrontmatter 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 featurerightSidebar.minWidth: Minimum viewport width to show sidebar (default: 1135px)
rightSidebarfrontmatter 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.tswithfontFamilyoption - 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-wrapstyling 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.fastacross the application - Fixed
atom:link rel="self"attribute mismatch that caused RSS validation failures - Updated
index.htmlmeta tags (og:url, og:image, twitter:domain, twitter:url, twitter:image, JSON-LD) - Updated
convex/rss.tsandconvex/http.tsSITE_URL constants to use www.markdown.fast - Updated
public/robots.txt,public/openapi.yaml, andpublic/llms.txtwith www URLs - RSS exclusions already present in
netlify.tomlfor 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
undefinedto 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
/blogpage - Can be disabled by setting
enabled: false
- Configurable via
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
- Tags now link to
- 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/*.mdfiles 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)
- AI crawlers cannot reliably fetch
-
Workaround for users
- Copy page: copies markdown to clipboard, paste directly into any AI tool
- View as Markdown: opens raw
.mdfile 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/*.mdfiles 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.innerPageLogoandsiteConfig.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
-
showInNavfield for pages to control navigation visibility- Pages can be published and accessible but hidden from navigation menu
- Set
showInNav: falsein page frontmatter to hide from nav - Defaults to
truefor backwards compatibility (all existing pages show in nav) - Pages with
showInNav: falseremain:- 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.showInNavin siteConfig.ts
-
Hardcoded navigation items configuration for React routes
- Add React route pages (like
/stats,/write) to navigation viasiteConfig.hardcodedNavItems - Configure navigation order, title, and visibility per route
- Set
showInNav: falseto hide from nav while keeping route accessible - Navigation combines Blog link, hardcoded nav items, and markdown pages
- All nav items sorted by
orderfield (lower = first)
- Add React route pages (like
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.enabledandsiteConfig.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
inheritto match body font - Mobile menu TOC links use consistent sizing with desktop sidebar
- Added CSS variables:
--font-size-mobile-toc-titleand--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
imagefrontmatter 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 headerssrc/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
authorNameandauthorImagefrontmatter 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 configurecommand for one-step fork setup - Copy
fork-config.json.exampletofork-config.json - Edit the JSON file with your site information
- Run
npm run configureto apply all changes automatically
Two options for fork setup:
- Automated (recommended): JSON config file +
npm run configure - 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
/writepage 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
/writepage to matchThemeToggle.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
/writepage 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
/writepage 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
/writepage 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
imagein frontmatter now display their specific OG image when shared - Posts without images fall back to
og-default.svg - Pages now supported with
og:typeset 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
/blogpage 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
getStatsto 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/aggregatepackage for TableAggregate - Three aggregates: totalPageViews, pageViewsByPath, uniqueVisitors
- Backfill mutation for existing page view data
- Updated
convex/convex.config.tswith aggregate component registration - Updated
convex/stats.tsto use aggregate counts in getStats query - Updated
prds/howstatsworks.mdwith 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.txtwith sitemap URL and header - Updated
public/llms.txtwith site name and description - Updated
public/.well-known/ai-plugin.jsonfor AI plugins - Updated
public/openapi.yamlAPI title and site name - Updated
convex/http.tsSITE_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.mdwith 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 syncandnpm run sync:prodinpublic/raw/directory - Each published post and page gets a corresponding static
.mdfile - Includes metadata header (type, date, reading time, tags)
- Generated during
- View as Markdown option in CopyPageDropdown
- Opens raw
.mdfile in new tab - Available on all post and page views
- Opens raw
- Perplexity added to AI service options in CopyPageDropdown
- Research articles directly in Perplexity with full content
- Featured image support for posts and pages
imagefield 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:prodneeded - Updated docs: README, setup-guide, how-to-publish, docs page, about-this-blog
- Renamed
content/pages/changelog.mdtochangelog-page.mdto 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:prodcommand (import creates local files only)
- New
/api/exportendpoint for batch content fetching - AI plugin discovery at
/.well-known/ai-plugin.json - OpenAPI 3.0 specification at
/openapi.yaml - Enhanced
llms.txtwith 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: trueto any post or page frontmatter - Use
featuredOrderto control display order (lower = first) - Featured items sync instantly with
npm run sync(no redeploy needed)
New Convex queries:
getFeaturedPosts: returns posts withfeatured: truegetFeaturedPages: returns pages withfeatured: 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
excerptfield 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.tsproxies/rss.xmland/rss-full.xmlsitemap.tsproxies/sitemap.xmlapi.tsproxies/api/postsand/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.xmland/rss-full.xml - AI agent discovery with
llms.txt robots.txtwith rules for AI crawlers
API endpoints
/api/postsfor JSON list of all posts/api/post?slug=xxxfor 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