Files
wiki/content/pages/docs.md

6.4 KiB

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

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

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 variable: CONVEX_DEPLOY_KEY (from Convex Dashboard)

The build automatically sets VITE_CONVEX_URL from the deploy key.

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+)