Files
wiki/content/pages/docs.md
Wayne Sutton c492b338b4 fix: require VITE_CONVEX_URL env var for edge functions and clarify publishing workflow
- Add VITE_CONVEX_URL requirement to Netlify env vars for edge function runtime
- Improve error messages in edge functions when Convex URL is missing
- Add "How publishing works" explanation to README, setup guide, and docs
- Update deployment instructions across all documentation
2025-12-14 21:42:09 -08:00

6.8 KiB

title, slug, published, order
title slug published order
Docs docs true 0

Reference documentation for setting up, customizing, and deploying this markdown site.

How publishing works: Write posts in markdown, run npm run sync, and they appear on your live site immediately. No rebuild or redeploy needed. Convex handles real-time data sync, so connected browsers update automatically.

Quick start

git clone https://github.com/waynesutton/markdown-site.git
cd markdown-site
npm install
npx convex dev
npm run sync
npm run dev

Open http://localhost:5173 to view locally.

Requirements

  • Node.js 18+
  • Convex account (free at convex.dev)
  • Netlify account (free at netlify.com)

Project structure

markdown-site/
├── content/
│   ├── blog/           # Blog posts (.md)
│   └── pages/          # Static pages (.md)
├── convex/
│   ├── schema.ts       # Database schema
│   ├── posts.ts        # Post queries/mutations
│   ├── pages.ts        # Page queries/mutations
│   ├── http.ts         # API endpoints
│   └── rss.ts          # RSS generation
├── netlify/
│   └── edge-functions/ # Netlify edge functions
│       ├── rss.ts      # RSS proxy
│       ├── sitemap.ts  # Sitemap proxy
│       ├── api.ts      # API proxy
│       └── botMeta.ts  # OG crawler detection
├── src/
│   ├── components/     # React components
│   ├── context/        # Theme context
│   ├── pages/          # Route components
│   └── styles/         # CSS
├── public/
│   ├── images/         # Static images
│   ├── robots.txt      # Crawler rules
│   └── llms.txt        # AI discovery
└── netlify.toml        # Deployment config

Content

Blog posts

Create files in content/blog/ with frontmatter:

---
title: "Post Title"
description: "SEO description"
date: "2025-01-15"
slug: "url-path"
published: true
tags: ["tag1", "tag2"]
readTime: "5 min read"
image: "/images/og-image.png"
---

Content here...
Field Required Description
title Yes Post title
description Yes SEO description
date Yes YYYY-MM-DD format
slug Yes URL path (unique)
published Yes true to show
tags Yes Array of strings
readTime No Display time estimate
image No Open Graph image

Static pages

Create files in content/pages/ with frontmatter:

---
title: "Page Title"
slug: "url-path"
published: true
order: 1
---

Content here...
Field Required Description
title Yes Nav link text
slug Yes URL path
published Yes true to show
order No Nav order (lower = first)

Syncing content

# Development
npm run sync

# Production
npm run sync:prod

Configuration

Site settings

Edit src/pages/Home.tsx:

const siteConfig = {
  name: "Site Name",
  title: "Tagline",
  logo: "/images/logo.svg", // null to hide
  intro: "Introduction text...",
  bio: "Bio text...",
  featuredEssays: [{ title: "Post Title", slug: "post-slug" }],
  links: {
    docs: "/docs",
    convex: "https://convex.dev",
  },
};

Theme

Default: tan. Options: dark, light, tan, cloud.

Edit src/context/ThemeContext.tsx:

const DEFAULT_THEME: Theme = "tan";

Font

Edit src/styles/global.css:

body {
  /* Sans-serif */
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* Serif (default) */
  font-family: "New York", ui-serif, Georgia, serif;
}

Images

Image Location Size
Favicon public/favicon.svg 512x512
Site logo public/images/logo.svg 512x512
Default OG image public/images/og-default.svg 1200x630
Post images public/images/ Any

API endpoints

Endpoint Description
/rss.xml RSS feed (descriptions)
/rss-full.xml RSS feed (full content)
/sitemap.xml XML sitemap
/api/posts JSON post list
/api/post?slug=xxx Single post (JSON)
/api/post?slug=xxx&format=md Single post (markdown)

Deployment

Netlify setup

  1. Connect GitHub repo to Netlify
  2. Build command: npm ci --include=dev && npx convex deploy --cmd 'npm run build'
  3. Publish directory: dist
  4. Add env variables:
    • CONVEX_DEPLOY_KEY (from Convex Dashboard > Project Settings > Deploy Key)
    • VITE_CONVEX_URL (your production Convex URL, e.g., https://your-deployment.convex.cloud)

Both are required: deploy key for builds, URL for edge function runtime.

Convex production

npx convex deploy

Edge functions

RSS, sitemap, and API routes are handled by Netlify Edge Functions in netlify/edge-functions/. They dynamically read VITE_CONVEX_URL from the environment. No manual URL configuration needed.

Convex schema

// convex/schema.ts
export default defineSchema({
  posts: defineTable({
    slug: v.string(),
    title: v.string(),
    description: v.string(),
    content: v.string(),
    date: v.string(),
    published: v.boolean(),
    tags: v.array(v.string()),
    readTime: v.optional(v.string()),
    image: v.optional(v.string()),
    lastSyncedAt: v.number(),
  })
    .index("by_slug", ["slug"])
    .index("by_published", ["published"]),

  pages: defineTable({
    slug: v.string(),
    title: v.string(),
    content: v.string(),
    published: v.boolean(),
    order: v.optional(v.number()),
    lastSyncedAt: v.number(),
  })
    .index("by_slug", ["slug"])
    .index("by_published", ["published"]),
});

Troubleshooting

Posts not appearing

  • Check published: true in frontmatter
  • Run npm run sync
  • Verify in Convex dashboard

RSS/Sitemap errors

  • Verify VITE_CONVEX_URL is set in Netlify
  • Test Convex HTTP URL: https://your-deployment.convex.site/rss.xml
  • Check edge functions in netlify/edge-functions/

Build failures

  • Verify CONVEX_DEPLOY_KEY is set in Netlify
  • Ensure @types/node is in devDependencies
  • Build command must include --include=dev
  • Check Node.js version (18+)