mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-11 20:08:57 +00:00
Add missing changelog entries to content/pages/changelog-page.md: v1.34.0 (2025-12-26): Blog page featured layout with hero post - blogFeatured frontmatter field for posts - Hero card displays first featured post with landscape image - 2-column featured row for remaining featured posts - 3-column grid for regular posts v1.35.0 (2025-12-26): Image support at top of posts and pages - showImageAtTop frontmatter field - Full-width image display above post header - Works for both posts and pages v1.36.0 (2025-12-27): Social footer component - Customizable social links (8 platform types) - Copyright with auto-updating year - showSocialFooter frontmatter field for per-page control - Configurable via siteConfig.socialFooter v1.37.0 (2025-12-27): Newsletter Admin UI - Three-column admin interface at /newsletter-admin - Subscriber management with search and filters - Send newsletter panel (post selection or custom email) - Weekly digest automation (Sunday 9am UTC) - Developer notifications (subscriber alerts, weekly stats) - Markdown-to-HTML conversion for custom emails
4.9 KiB
4.9 KiB
AgentMail Newsletter Integration v1
Overview
Email-only newsletter system integrated with AgentMail. All features are optional and controlled via siteConfig.ts and frontmatter.
Implemented Features
Phase 1: Newsletter Signup
| Feature | Status | Description |
|---|---|---|
| Site Config | Done | NewsletterConfig interface in siteConfig.ts |
| Schema | Done | newsletterSubscribers table with indexes |
| Subscribe Mutation | Done | Email validation, duplicate detection, re-subscribe support |
| Unsubscribe Mutation | Done | Token verification for security |
| Subscriber Queries | Done | getSubscriberCount, getActiveSubscribers |
| NewsletterSignup Component | Done | Email input form with status feedback |
| CSS Styling | Done | Responsive styles for all themes |
| Home Integration | Done | Configurable position (above-footer, below-intro) |
| Blog Page Integration | Done | Configurable position (above-footer, below-posts) |
| Post Integration | Done | Frontmatter override support |
| Unsubscribe Page | Done | /unsubscribe route with auto-processing |
Phase 2: Newsletter Sending
| Feature | Status | Description |
|---|---|---|
| Sent Posts Schema | Done | newsletterSentPosts table to track sent newsletters |
| Send Action | Done | sendPostNewsletter internalAction using AgentMail API |
| CLI Script | Done | npm run newsletter:send <slug> |
Files Created/Modified
New Files
convex/newsletter.ts- Subscribe, unsubscribe, and sending functionssrc/components/NewsletterSignup.tsx- React componentsrc/pages/Unsubscribe.tsx- Unsubscribe pagescripts/send-newsletter.ts- CLI tool for sending newslettersprds/agentmail-newsletter-v1.md- This file
Modified Files
src/config/siteConfig.ts- AddedNewsletterConfiginterfaceconvex/schema.ts- AddednewsletterSubscribersandnewsletterSentPoststablesconvex/posts.ts- AddedgetPostBySlugInternalquerysrc/styles/global.css- Added newsletter component stylessrc/pages/Home.tsx- IntegratedNewsletterSignupsrc/pages/Blog.tsx- IntegratedNewsletterSignupsrc/pages/Post.tsx- IntegratedNewsletterSignupwith frontmatter supportsrc/App.tsx- Added/unsubscriberoutepackage.json- Addednewsletter:sendscriptfork-config.json.example- Added newsletter configurationFORK_CONFIG.md- Added newsletter documentation
Configuration
Environment Variables (Convex Dashboard)
| Variable | Description |
|---|---|
AGENTMAIL_API_KEY |
Your AgentMail API key |
AGENTMAIL_INBOX |
Your inbox address (e.g., newsletter@mail.agentmail.to) |
Site Config Example
newsletter: {
enabled: true,
agentmail: {
inbox: "newsletter@mail.agentmail.to",
},
signup: {
home: {
enabled: true,
position: "above-footer",
title: "Stay Updated",
description: "Get new posts delivered to your inbox.",
},
blogPage: {
enabled: true,
position: "above-footer",
title: "Subscribe",
description: "Get notified when new posts are published.",
},
posts: {
enabled: true,
position: "below-content",
title: "Enjoyed this post?",
description: "Subscribe for more updates.",
},
},
},
Frontmatter Override
---
title: My Post
newsletter: false # Hide newsletter on this post
---
Usage
Collect Subscribers
- Enable newsletter in
siteConfig.ts - Set environment variables in Convex dashboard
- Subscribers can sign up from homepage, blog page, or individual posts
Send Newsletter
# Check post exists and show send command
npm run newsletter:send <post-slug>
# Or use Convex CLI directly
npx convex run newsletter:sendPostNewsletter '{"postSlug":"slug","siteUrl":"https://site.com","siteName":"Name"}'
View Subscriber Count
Subscriber count is available via the newsletter.getSubscriberCount query.
Database Schema
newsletterSubscribers
| Field | Type | Description |
|---|---|---|
| string | Subscriber email (lowercase, trimmed) | |
| subscribed | boolean | Current subscription status |
| subscribedAt | number | Timestamp when subscribed |
| unsubscribedAt | number? | Timestamp when unsubscribed |
| source | string | Signup location ("home", "blog-page", "post:slug") |
| unsubscribeToken | string | Secure token for unsubscribe links |
Indexes: by_email, by_subscribed
newsletterSentPosts
| Field | Type | Description |
|---|---|---|
| postSlug | string | Slug of the sent post |
| sentAt | number | Timestamp when sent |
| sentCount | number | Number of subscribers sent to |
Index: by_postSlug
Future Enhancements (Not Implemented)
- Double opt-in confirmation emails
- Contact form integration
- Weekly digest automation
- Subscriber admin UI in dashboard
- Email templates customization