feature: new dashboard workos auth for dashboard login, dashboard optional in site config, sync server for dashboard, workos and dashboard docs updated

This commit is contained in:
Wayne Sutton
2025-12-29 22:11:52 -08:00
parent f6c9478c9d
commit e8d09fcce2
47 changed files with 15058 additions and 193 deletions

View File

@@ -0,0 +1,315 @@
---
title: "How to setup WorkOS"
description: "Step-by-step guide to configure WorkOS AuthKit authentication for your markdown blog dashboard. WorkOS is optional and can be enabled in siteConfig.ts."
date: "2025-12-29"
slug: "how-to-setup-workos"
published: true
tags: ["workos", "authentication", "tutorial", "dashboard"]
readTime: "10 min read"
featured: true
featuredOrder: 3
excerpt: "Complete guide to setting up WorkOS AuthKit authentication for your dashboard. WorkOS is optional and can be configured in siteConfig.ts."
---
# How to setup WorkOS
WorkOS AuthKit adds authentication to your markdown blog dashboard. It's optional—you can use the dashboard without WorkOS, or enable authentication for production sites.
## Overview
WorkOS AuthKit provides:
- Password authentication
- Social login (Google, GitHub, etc.)
- SSO support
- User management
- Session handling
The dashboard at `/dashboard` can work with or without WorkOS. Configure it in `siteConfig.ts`:
```typescript
dashboard: {
enabled: true,
requireAuth: false, // Set to true to require WorkOS authentication
},
```
When `requireAuth` is `false`, the dashboard is open access. When `requireAuth` is `true` and WorkOS is configured, users must log in to access the dashboard.
## Prerequisites
Before starting, make sure you have:
- Node.js 18 or higher
- A working markdown blog project
- A Convex account and project set up
- Your Convex development server running (`npx convex dev`)
## Step 1: Create a WorkOS account
### Sign up
1. Go to [workos.com/sign-up](https://signin.workos.com/sign-up)
2. Create a free account with your email
3. Verify your email address
### Set up AuthKit
1. Log into the [WorkOS Dashboard](https://dashboard.workos.com)
2. Navigate to **Authentication****AuthKit**
3. Click the **Set up AuthKit** button
4. Select **"Use AuthKit's customizable hosted UI"**
5. Click **Begin setup**
### Configure redirect URI
During the AuthKit setup wizard, you'll reach step 4: **"Add default redirect endpoint URI"**
Enter this for local development:
```
http://localhost:5173/callback
```
After a user logs in, WorkOS redirects them back to this URL with an authorization code. Your app exchanges this code for user information.
### Copy your credentials
1. Go to [dashboard.workos.com/get-started](https://dashboard.workos.com/get-started)
2. Under **Quick start**, find and copy:
- **Client ID** (looks like `client_01XXXXXXXXXXXXXXXXX`)
Save this somewhere safe—you'll need it shortly.
## Step 2: Configure WorkOS dashboard
### Enable CORS
For the React SDK to work, you need to allow your app's domain:
1. Go to **Authentication****Sessions** in the WorkOS Dashboard
2. Find **Cross-Origin Resource Sharing (CORS)**
3. Click **Manage**
4. Add your development URL: `http://localhost:5173`
5. Click **Save**
When you deploy to production (e.g., Netlify), add your production domain here too (e.g., `https://yoursite.netlify.app`).
### Verify redirect URI
1. Go to **Redirects** in the WorkOS Dashboard
2. Confirm `http://localhost:5173/callback` is listed
3. If not, add it by clicking **Add redirect**
## Step 3: Install dependencies
Open your terminal in the project folder and install the required packages:
```bash
npm install @workos-inc/authkit-react @convex-dev/workos
```
**What these packages do:**
| Package | Purpose |
|---------|---------|
| `@workos-inc/authkit-react` | WorkOS React SDK for handling login/logout |
| `@convex-dev/workos` | Bridges WorkOS auth with Convex backend |
## Step 4: Add environment variables
### Update `.env.local`
Open your `.env.local` file (in the project root) and add these lines:
```env
# Existing Convex URL (should already be here)
VITE_CONVEX_URL=https://your-deployment.convex.cloud
# WorkOS AuthKit Configuration (add these)
VITE_WORKOS_CLIENT_ID=client_01XXXXXXXXXXXXXXXXX
VITE_WORKOS_REDIRECT_URI=http://localhost:5173/callback
```
Replace `client_01XXXXXXXXXXXXXXXXX` with your actual Client ID from the WorkOS Dashboard.
Vite only exposes environment variables that start with `VITE_` to the browser.
### Add to `.gitignore`
Make sure `.env.local` is in your `.gitignore` to avoid committing secrets:
```
.env.local
.env.production.local
```
## Step 5: Configure Convex auth
Create a new file to tell Convex how to validate WorkOS tokens.
### Create `convex/auth.config.ts`
Create a new file at `convex/auth.config.ts`:
```typescript
// convex/auth.config.ts
const clientId = process.env.WORKOS_CLIENT_ID;
const authConfig = {
providers: [
{
type: "customJwt",
issuer: "https://api.workos.com/",
algorithm: "RS256",
applicationID: clientId,
jwks: `https://api.workos.com/sso/jwks/${clientId}`,
},
{
type: "customJwt",
issuer: `https://api.workos.com/user_management/${clientId}`,
algorithm: "RS256",
jwks: `https://api.workos.com/sso/jwks/${clientId}`,
},
],
};
export default authConfig;
```
### Add environment variable to Convex
The Convex backend needs the Client ID too:
1. Run `npx convex dev` if not already running
2. You'll see an error with a link—click it
3. It takes you to the Convex Dashboard environment variables page
4. Add a new variable:
- **Name**: `WORKOS_CLIENT_ID`
- **Value**: Your WorkOS Client ID (e.g., `client_01XXXXXXXXXXXXXXXXX`)
5. Save
After saving, `npx convex dev` should show "Convex functions ready."
## Step 6: Update site configuration
Enable authentication in your site config:
```typescript
// src/config/siteConfig.ts
dashboard: {
enabled: true,
requireAuth: true, // Set to true to require WorkOS authentication
},
```
When `requireAuth` is `true` and WorkOS is configured, the dashboard requires login. When `requireAuth` is `false`, the dashboard is open access.
## Step 7: Test locally
1. Start your development server:
```bash
npm run dev
```
2. Navigate to `http://localhost:5173/dashboard`
3. You should see a login prompt (if `requireAuth: true`) or the dashboard (if `requireAuth: false`)
4. If authentication is enabled, click "Sign in" to test the WorkOS login flow
5. After logging in, you should be redirected back to the dashboard
## Step 8: Deploy to production
### Add production environment variables
In your Netlify dashboard (or hosting provider), add these environment variables:
- `VITE_WORKOS_CLIENT_ID` - Your WorkOS Client ID
- `VITE_WORKOS_REDIRECT_URI` - Your production callback URL (e.g., `https://yoursite.netlify.app/callback`)
### Update WorkOS redirect URI
1. Go to **Redirects** in the WorkOS Dashboard
2. Add your production callback URL: `https://yoursite.netlify.app/callback`
3. Click **Save**
### Update CORS settings
1. Go to **Authentication** → **Sessions** in the WorkOS Dashboard
2. Find **Cross-Origin Resource Sharing (CORS)**
3. Click **Manage**
4. Add your production domain: `https://yoursite.netlify.app`
5. Click **Save**
### Add Convex environment variable
In your Convex Dashboard, add the `WORKOS_CLIENT_ID` environment variable for your production deployment:
1. Go to [dashboard.convex.dev](https://dashboard.convex.dev)
2. Select your production project
3. Navigate to Settings → Environment Variables
4. Add `WORKOS_CLIENT_ID` with your Client ID value
5. Save
## How it works
When WorkOS is configured and `requireAuth: true`:
1. User navigates to `/dashboard`
2. Dashboard checks authentication status
3. If not authenticated, shows login prompt
4. User clicks "Sign in" and is redirected to WorkOS
5. User logs in with WorkOS (password, social, or SSO)
6. WorkOS redirects back to `/callback` with authorization code
7. App exchanges code for user information
8. User is redirected to `/dashboard` as authenticated user
When WorkOS is not configured or `requireAuth: false`:
1. User navigates to `/dashboard`
2. Dashboard shows content directly (no authentication required)
## Troubleshooting
**Dashboard shows "Authentication Required" message:**
- Verify `VITE_WORKOS_CLIENT_ID` and `VITE_WORKOS_REDIRECT_URI` are set in `.env.local`
- Check that `WORKOS_CLIENT_ID` is set in Convex environment variables
- Ensure `requireAuth: true` in `siteConfig.ts`
**Login redirect not working:**
- Verify redirect URI matches exactly in WorkOS Dashboard
- Check CORS settings include your domain
- Ensure callback route is configured in `App.tsx`
**"WorkOS is not configured" message:**
- Check that both `VITE_WORKOS_CLIENT_ID` and `VITE_WORKOS_REDIRECT_URI` are set
- Verify environment variables are loaded (check browser console)
- Restart development server after adding environment variables
**Convex auth errors:**
- Verify `WORKOS_CLIENT_ID` is set in Convex environment variables
- Check that `convex/auth.config.ts` exists and is correct
- Ensure Convex functions are deployed (`npx convex deploy`)
## Optional configuration
WorkOS is optional. You can:
- Use the dashboard without WorkOS (`requireAuth: false`)
- Enable WorkOS later when you need authentication
- Configure WorkOS for production only
The dashboard works with or without WorkOS. Configure it based on your needs.
## Next steps
After setting up WorkOS:
1. Test the authentication flow locally
2. Deploy to production with production environment variables
3. Add additional redirect URIs if needed
4. Configure social login providers in WorkOS Dashboard
5. Set up SSO if needed for your organization
See [How to use the Markdown sync dashboard](https://www.markdown.fast/how-to-use-the-markdown-sync-dashboard) for dashboard usage.

View File

@@ -0,0 +1,269 @@
---
title: "How to use the Markdown sync dashboard"
description: "Learn how to use the dashboard at /dashboard to manage content, configure your site, and sync markdown files without leaving your browser."
date: "2025-12-29"
slug: "how-to-use-the-markdown-sync-dashboard"
published: true
tags: ["dashboard", "tutorial", "content-management"]
readTime: "8 min read"
featured: true
featuredOrder: 2
excerpt: "A complete guide to using the dashboard for managing your markdown blog without leaving your browser."
---
# How to use the Markdown sync dashboard
The dashboard at `/dashboard` gives you a centralized interface for managing your markdown blog. You can edit posts, sync content, configure settings, and more without switching between your editor and terminal.
## Accessing the dashboard
Navigate to `/dashboard` in your browser. The dashboard isn't linked in the navigation by default, so you'll access it directly via URL.
### Authentication
The dashboard supports optional WorkOS authentication. Configure it in `siteConfig.ts`:
```typescript
dashboard: {
enabled: true,
requireAuth: false, // Set to true to require WorkOS authentication
},
```
When `requireAuth` is `false`, the dashboard is open to anyone who knows the URL. For production sites, set `requireAuth: true` and configure WorkOS authentication. See [How to setup WorkOS](https://www.markdown.fast/how-to-setup-workos) for authentication setup.
If WorkOS isn't configured and `requireAuth` is `true`, the dashboard shows setup instructions instead of the login prompt.
## Content management
### Posts and pages list
View all your posts and pages in one place. Each list includes:
- Filter by status: All, Published, Drafts
- Search by title or content
- Pagination with "First" and "Next" buttons
- Items per page selector (15, 25, 50, 100)
- Quick actions: Edit, View, Publish/Unpublish
Posts and pages display with their titles, publication status, and last modified dates. Click any item to open the editor.
### Post and page editor
Edit markdown content with a live preview. The editor includes:
- Markdown editor on the left
- Live preview on the right showing how content appears on your site
- Draggable frontmatter sidebar (200px-600px width)
- Independent scrolling for editor and preview sections
- Download markdown button to save changes locally
- Copy to clipboard for quick sharing
The frontmatter sidebar shows all available fields with descriptions. Edit values directly, and changes appear in the preview immediately.
### Write post and write page
Create new content without leaving the dashboard. The write interface includes:
- Full-screen markdown editor
- Frontmatter reference panel with copy buttons
- Word, line, and character counts
- Download markdown button
- Content persists in localStorage
Write your content, fill in frontmatter fields, then download the markdown file. Save it to `content/blog/` or `content/pages/`, then sync to Convex.
## AI Agent
The dashboard includes a dedicated AI chat section separate from the Write page. Use it for:
- Writing assistance
- Content suggestions
- Editing help
- Answering questions about your content
The AI Agent uses Anthropic Claude API and requires `ANTHROPIC_API_KEY` in your Convex environment variables. Chat history is stored per-session in Convex.
## Newsletter management
All Newsletter Admin features are integrated into the dashboard:
- Subscribers: View, search, filter, and delete subscribers
- Send newsletter: Select a blog post to send to all active subscribers
- Write email: Compose custom emails with markdown support
- Recent sends: View the last 10 newsletter sends (posts and custom emails)
- Email stats: Dashboard with total emails sent, newsletters sent, active subscribers, and retention rate
Newsletter features require AgentMail configuration. Set `AGENTMAIL_API_KEY` and `AGENTMAIL_INBOX` in your Convex environment variables.
## Content import
Import articles from external URLs using Firecrawl:
1. Enter the URL you want to import
2. Click "Import"
3. Review the imported markdown draft
4. Edit if needed, then sync to Convex
Imported posts are created as drafts (`published: false`) by default. Review, edit, set `published: true`, then sync.
Firecrawl import requires `FIRECRAWL_API_KEY` in your `.env.local` file.
## Site configuration
The Config Generator UI lets you configure all `siteConfig.ts` settings from the dashboard:
- Site name, title, logo, bio
- Blog page settings
- Featured section configuration
- Logo gallery settings
- GitHub contributions
- Footer and social footer
- Newsletter settings
- Contact form settings
- Stats page settings
- Dashboard settings
Make changes in the UI, then download the generated `siteConfig.ts` file. Replace your existing config file with the downloaded version.
## Index HTML editor
View and edit `index.html` content directly:
- Meta tags
- Open Graph tags
- Twitter Cards
- JSON-LD structured data
Edit values in the UI, then download the updated HTML file. Replace your existing `index.html` with the downloaded version.
## Analytics
The dashboard includes a real-time stats section (clone of `/stats` page):
- Active visitors with per-page breakdown
- Total page views
- Unique visitors
- Views by page sorted by popularity
Stats update automatically via Convex subscriptions. No page refresh needed.
## Sync commands
Run sync operations from the dashboard without opening a terminal:
**Development:**
- `npm run sync` - Sync markdown content
- `npm run sync:discovery` - Update discovery files (AGENTS.md, llms.txt)
- `npm run sync:all` - Sync content + discovery files together
**Production:**
- `npm run sync:prod` - Sync markdown content
- `npm run sync:discovery:prod` - Update discovery files
- `npm run sync:all:prod` - Sync content + discovery files together
### Sync server
For the best experience, start the sync server to execute commands directly from the dashboard:
```bash
npm run sync-server
```
This starts a local HTTP server on `localhost:3001` that allows the dashboard to execute sync commands and stream output in real-time.
**When sync server is running:**
- Server status shows "Online" in the sync section
- "Execute" buttons appear for each sync command
- Clicking Execute runs the command and streams output to the terminal view
- Real-time output appears as the command runs
- No need to copy commands to your terminal
**When sync server is offline:**
- Server status shows "Offline" in the sync section
- Only "Copy" buttons appear for each sync command
- Clicking Copy shows the command in a modal for copying to your terminal
- Copy icon appears next to `npm run sync-server` command to help you start the server
**Security:**
- Server binds to localhost only (not accessible from network)
- Optional token authentication via `SYNC_TOKEN` environment variable
- Only whitelisted commands can be executed
- CORS enabled for localhost:5173 (dev server)
### Header sync buttons
Quick sync buttons in the dashboard header let you run `npm run sync:all` (dev and prod) with one click. These buttons automatically use the sync server when available, or show the command in a modal when the server is offline.
## Dashboard features
### Search
The search bar in the dashboard header searches:
- Dashboard features and sections
- Page titles
- Post content
Results appear as you type. Click any result to navigate to that section or content.
### Theme and font
Toggle between themes (dark, light, tan, cloud) and switch fonts (serif, sans, monospace) from the dashboard. Preferences persist across sessions.
### Toast notifications
Success, error, info, and warning notifications appear in the top-right corner. They auto-dismiss after 4 seconds and are theme-aware.
### Command modal
When you run sync commands, output appears in a modal. You can:
- View full command output
- Copy command to clipboard
- Close the modal
### Mobile responsive
The dashboard works on mobile devices with:
- Collapsible sidebar
- Touch-friendly controls
- Responsive tables and forms
- Mobile-optimized layout
## Best practices
1. Use the editor for quick edits and previews
2. Download markdown files for version control
3. Sync regularly to keep content up to date
4. Use the AI Agent for writing assistance
5. Check analytics to see what content performs well
6. Configure WorkOS authentication for production sites
## Troubleshooting
**Dashboard not loading:**
- Check that `dashboard.enabled: true` in `siteConfig.ts`
- Verify Convex is running (`npx convex dev`)
- Check browser console for errors
**Sync commands failing:**
- Ensure you're in the project root directory
- Check that Convex environment variables are set
- Verify `.env.local` or `.env.production.local` exists
**Authentication not working:**
- Verify WorkOS environment variables are set
- Check that `requireAuth: true` in `siteConfig.ts`
- See [How to setup WorkOS](https://www.markdown.fast/how-to-setup-workos) for setup instructions
The dashboard makes managing your markdown blog easier. You can edit content, sync files, and configure settings all from one place.

View File

@@ -16,7 +16,9 @@ image: "/images/markdown.png"
# Writing Markdown with Code Examples
This post demonstrates how to write markdown content with code blocks, tables, and formatting. Use it as a reference when creating your own posts.
This post is the complete reference for all markdown syntax used in this framework. It includes copy-paste examples for code blocks, tables, lists, links, images, collapsible sections, and all formatting options.
**Use this post as your reference** when writing blog posts or pages. All examples are ready to copy and paste directly into your markdown files.
## Frontmatter

View File

@@ -1589,6 +1589,67 @@ Agent requires the following Convex environment variables:
If `ANTHROPIC_API_KEY` is not configured in Convex environment variables, Agent displays a user-friendly error message: "API key is not set". This helps identify when the API key is missing in production deployments.
## Dashboard
The Dashboard at `/dashboard` provides a centralized UI for managing content, configuring the site, and performing sync operations. It's designed for developers who fork the repository to set up and manage their markdown blog.
**Access:** Navigate to `/dashboard` in your browser. The dashboard is not linked in the navigation by default.
**Authentication:** WorkOS authentication is optional. Configure it in `siteConfig.ts`:
```typescript
dashboard: {
enabled: true,
requireAuth: false, // Set to true to require WorkOS authentication
},
```
When `requireAuth` is `false`, the dashboard is open access. When `requireAuth` is `true` and WorkOS is configured, users must log in to access the dashboard. See [How to setup WorkOS](https://www.markdown.fast/how-to-setup-workos) for authentication setup.
**Key Features:**
- **Content Management:** Posts and Pages list views with filtering, search, pagination, and items per page selector
- **Post/Page Editor:** Markdown editor with live preview, draggable/resizable frontmatter sidebar, download markdown
- **Write Post/Page:** Full-screen writing interface with markdown editor and frontmatter reference
- **AI Agent:** Dedicated AI chat section separate from Write page
- **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
- **Index HTML Editor:** View and edit `index.html` content
- **Analytics:** Real-time stats dashboard (always accessible in dashboard)
- **Sync Commands:** UI with buttons for all sync operations (sync, sync:discovery, sync:all for dev and prod)
- **Sync Server:** Execute sync commands directly from dashboard with real-time output
- **Header Sync Buttons:** Quick sync buttons in dashboard header for `npm run sync:all` (dev and prod)
**Sync Commands Available:**
- `npm run sync` - Sync markdown content (development)
- `npm run sync:prod` - Sync markdown content (production)
- `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 (development)
- `npm run sync:all:prod` - Sync content + discovery files (production)
- `npm run sync-server` - Start local HTTP server for executing commands from dashboard
**Sync Server:**
The dashboard can execute sync commands directly without opening a terminal. Start the sync server:
```bash
npm run sync-server
```
This starts a local HTTP server on `localhost:3001` that:
- Executes sync commands when requested from the dashboard
- Streams output in real-time to the dashboard terminal view
- Shows server status (online/offline) in the dashboard
- Supports optional token authentication via `SYNC_TOKEN` environment variable
- Only executes whitelisted commands for security
When the sync server is running, the dashboard shows "Execute" buttons that run commands directly. When offline, buttons show commands in a modal for copying to your terminal.
The dashboard provides a UI for these commands, but you can also run them directly from the terminal. See the [Dashboard documentation](/docs#dashboard) for complete details.
## Next Steps
After deploying:

View File

@@ -9,6 +9,108 @@ layout: "sidebar"
All notable changes to this project.
![](https://img.shields.io/badge/License-MIT-yellow.svg)
## 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

View File

@@ -83,6 +83,8 @@ markdown-site/
## Content
**Markdown examples:** For complete markdown syntax examples including code blocks, tables, lists, links, images, collapsible sections, and all formatting options, see [Writing Markdown with Code Examples](/markdown-with-code-examples). That post includes copy-paste examples for every markdown feature.
### Blog posts
Create files in `content/blog/` with frontmatter:
@@ -1003,6 +1005,206 @@ npm run newsletter:send setup-guide
The `newsletter:send` command calls the `scheduleSendPostNewsletter` mutation directly and sends emails in the background. Check the Newsletter Admin page or recent sends to see results.
## Dashboard
The Dashboard at `/dashboard` provides a centralized UI for managing content, configuring the site, and performing sync operations. It's designed for developers who fork the repository to set up and manage their markdown blog.
**Access:** Navigate to `/dashboard` in your browser. The dashboard is not linked in the navigation by default (similar to Newsletter Admin pattern).
**Authentication:** WorkOS authentication is optional. Configure it in `siteConfig.ts`:
```typescript
dashboard: {
enabled: true,
requireAuth: false, // Set to true to require WorkOS authentication
},
```
When `requireAuth` is `false`, the dashboard is open access. When `requireAuth` is `true` and WorkOS is configured, users must log in to access the dashboard. See [How to setup WorkOS](https://www.markdown.fast/how-to-setup-workos) for authentication setup.
### Content Management
**Posts and Pages List Views:**
- View all posts and pages (published and unpublished)
- Filter by status: All, Published, Drafts
- Search by title or content
- Pagination with "First" and "Next" buttons
- Items per page selector (15, 25, 50, 100) - default: 15
- Edit, view, and publish/unpublish options
- WordPress-style UI with date, edit, view, and publish controls
**Post and Page Editor:**
- Markdown editor with live preview
- Frontmatter sidebar on the right with all available fields
- Draggable/resizable frontmatter sidebar (200px-600px width)
- Independent scrolling for frontmatter sidebar
- Preview mode shows content as it appears on the live site
- Download markdown button to generate `.md` files
- Copy markdown to clipboard
- All frontmatter fields editable in sidebar
- Preview uses ReactMarkdown with proper styling
**Write Post and Write Page:**
- Full-screen writing interface
- Markdown editor with word/line/character counts
- Frontmatter reference panel
- Download markdown button for new content
- Content persists in localStorage
- Separate storage for post and page content
### AI Agent
- Dedicated AI chat section separate from the Write page
- Uses Anthropic Claude API (requires `ANTHROPIC_API_KEY` in Convex environment)
- Per-session chat history stored in Convex
- Markdown rendering for AI responses
- Copy functionality for AI responses
### Newsletter Management
All Newsletter Admin features integrated into the Dashboard:
- **Subscribers:** View, search, filter, and delete subscribers
- **Send Newsletter:** Select a blog post to send as newsletter
- **Write Email:** Compose custom emails with markdown support
- **Recent Sends:** View last 10 newsletter sends (posts and custom emails)
- **Email Stats:** Dashboard with total emails, newsletters sent, active subscribers, retention rate
All newsletter sections are full-width in the dashboard content area.
### Content Import
**Firecrawl Import:**
- Import articles from external URLs using Firecrawl API
- Requires `FIRECRAWL_API_KEY` in `.env.local`
- Creates local markdown drafts in `content/blog/`
- Imported posts are drafts (`published: false`) by default
- Review, edit, set `published: true`, then sync
### Site Configuration
**Config Generator:**
- UI to configure all settings in `src/config/siteConfig.ts`
- Generates downloadable `siteConfig.ts` file
- Hybrid approach: dashboard generates config, file-based config continues to work
- Includes all site configuration options:
- Site name, title, logo, bio, intro
- Blog page settings
- Featured section configuration
- Logo gallery settings
- GitHub contributions
- Footer and social footer
- Newsletter settings
- Contact form settings
- Stats page settings
- And more
**Index HTML Editor:**
- View and edit `index.html` content
- Meta tags, Open Graph, Twitter Cards, JSON-LD
- Download updated HTML file
### Analytics
- Real-time stats dashboard (clone of `/stats` page)
- Active visitors with per-page breakdown
- Total page views and unique visitors
- Views by page sorted by popularity
- Does not follow `siteConfig.statsPage` settings (always accessible in dashboard)
### Sync Commands
**Sync Content Section:**
- UI with buttons for all sync operations
- Development sync commands:
- `npm run sync` - Sync markdown content
- `npm run sync:discovery` - Update discovery files (AGENTS.md, llms.txt)
- `npm run sync:all` - Sync content + discovery files together
- Production sync commands:
- `npm run sync:prod` - Sync markdown content
- `npm run sync:discovery:prod` - Update discovery files
- `npm run sync:all:prod` - Sync content + discovery files together
- Server status indicator shows if sync server is online
- Copy and Execute buttons for each command
- Real-time terminal output when sync server is running
- Command modal shows full command output when sync server is offline
- Toast notifications for success/error feedback
**Sync Server:**
- Local HTTP server for executing commands from dashboard
- Start with `npm run sync-server` (runs on localhost:3001)
- Execute commands directly from dashboard with real-time output streaming
- Optional token authentication via `SYNC_TOKEN` environment variable
- Whitelisted commands only for security
- Health check endpoint for server availability detection
- Copy icons for `npm run sync-server` command in dashboard
**Header Sync Buttons:**
- Quick sync buttons in dashboard header (right side)
- `npm run sync:all` (dev) button
- `npm run sync:all:prod` (prod) button
- One-click sync for all content and discovery files
- Automatically use sync server when available, fallback to command modal
### Dashboard Features
**Search:**
- Search bar in header
- Search dashboard features, page titles, and post content
- Real-time results as you type
**Theme and Font:**
- Theme toggle (dark, light, tan, cloud)
- Font switcher (serif, sans, monospace)
- Preferences persist across sessions
**Mobile Responsive:**
- Fully responsive design
- Mobile-optimized layout
- Touch-friendly controls
- Collapsible sidebar on mobile
**Toast Notifications:**
- Success, error, info, and warning notifications
- Auto-dismiss after 4 seconds
- Theme-aware styling
- No browser default alerts
**Command Modal:**
- Shows sync command output
- Copy command to clipboard
- Close button to dismiss
- Theme-aware styling
### Technical Details
- Uses Convex queries for real-time data
- All mutations follow Convex best practices (idempotent, indexed queries)
- Frontmatter sidebar width persisted in localStorage
- Editor content persisted in localStorage
- Independent scrolling for editor and sidebar sections
- Preview uses ReactMarkdown with remark-gfm, remark-breaks, rehype-raw, rehype-sanitize
### Sync Commands Reference
**Development:**
- `npm run sync` - Sync markdown content to development Convex
- `npm run sync:discovery` - Update discovery files (AGENTS.md, llms.txt) with development data
- `npm run sync:all` - Run both content sync and discovery sync (development)
**Production:**
- `npm run sync:prod` - Sync markdown content to production Convex
- `npm run sync:discovery:prod` - Update discovery files with production data
- `npm run sync:all:prod` - Run both content sync and discovery sync (production)
**Sync Server:**
- `npm run sync-server` - Start local HTTP server for executing sync commands from dashboard UI
**Content Import:**
- `npm run import <url>` - Import external URL as markdown post (requires FIRECRAWL_API_KEY)
**Note:** The dashboard provides a UI for these commands. When the sync server is running (`npm run sync-server`), you can execute commands directly from the dashboard with real-time output. Otherwise, the dashboard shows commands in a modal for copying to your terminal.
## API endpoints
| Endpoint | Description |
@@ -1077,49 +1279,18 @@ When you run `npm run sync` (development) or `npm run sync:prod` (production), s
These files include a metadata header with type, date, reading time, and tags. Access via the "View as Markdown" option in the Copy Page dropdown.
## Markdown tables
## Markdown formatting
Tables render with GitHub-style formatting:
For complete markdown syntax examples including tables, collapsible sections, code blocks, lists, links, images, and all formatting options, see [Writing Markdown with Code Examples](/markdown-with-code-examples).
- Clean borders across all themes
- Mobile responsive with horizontal scroll
- Theme-aware alternating row colors
- Hover states for readability
**Quick reference:**
Example:
- **Tables:** Render with GitHub-style formatting, clean borders, mobile responsive
- **Collapsible sections:** Use HTML `<details>` and `<summary>` tags for expandable content
- **Code blocks:** Support syntax highlighting for TypeScript, JavaScript, bash, JSON, and more
- **Images:** Place in `public/images/` and reference with absolute paths
| Feature | Status |
| ------- | ------ |
| Borders | Clean |
| Mobile | Scroll |
| Themes | All |
## Collapsible sections
Create expandable/collapsible content using HTML `<details>` and `<summary>` tags:
```html
<details>
<summary>Click to expand</summary>
Hidden content here. Supports markdown: - Lists - **Bold** and _italic_ - Code
blocks
</details>
```
**Expanded by default:** Add the `open` attribute:
```html
<details open>
<summary>Already expanded</summary>
This section starts open.
</details>
```
**Nested sections:** You can nest `<details>` inside other `<details>` for multi-level collapsible content.
Collapsible sections work with all four themes and are styled to match the site design.
All markdown features work with all four themes and are styled to match the site design.
## Import external content

View File

@@ -7,7 +7,7 @@ order: -1
textAlign: "left"
---
An open-source publishing framework built for AI agents and developers to ship websites, docs, or blogs.
An open-source publishing framework built for AI agents and developers to ship **websites**, **docs**, or **blogs**.
Write markdown, sync from the terminal. [Fork it](https://github.com/waynesutton/markdown-site), customize it, ship it.