mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
update: moved footer to footer.md and docs updated
This commit is contained in:
@@ -22,7 +22,7 @@ Your content is instantly available to browsers, LLMs, and AI agents.. Write mar
|
|||||||
- **Total Posts**: 17
|
- **Total Posts**: 17
|
||||||
- **Total Pages**: 5
|
- **Total Pages**: 5
|
||||||
- **Latest Post**: 2025-12-29
|
- **Latest Post**: 2025-12-29
|
||||||
- **Last Updated**: 2025-12-30T20:03:38.734Z
|
- **Last Updated**: 2025-12-30T23:27:44.143Z
|
||||||
|
|
||||||
## Tech stack
|
## Tech stack
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Project instructions for Claude Code.
|
|||||||
## Project context
|
## Project context
|
||||||
|
|
||||||
<!-- Auto-updated by sync:discovery -->
|
<!-- Auto-updated by sync:discovery -->
|
||||||
<!-- Site: markdown | Posts: 17 | Pages: 5 | Updated: 2025-12-30T20:03:38.736Z -->
|
<!-- Site: markdown | Posts: 17 | Pages: 5 | Updated: 2025-12-30T23:27:44.146Z -->
|
||||||
|
|
||||||
Markdown sync framework. Write markdown in `content/`, run sync commands, content appears instantly via Convex real-time database. Built for developers and AI agents.
|
Markdown sync framework. Write markdown in `content/`, run sync commands, content appears instantly via Convex real-time database. Built for developers and AI agents.
|
||||||
|
|
||||||
@@ -61,6 +61,12 @@ npx convex deploy # Deploy Convex functions
|
|||||||
|
|
||||||
Netlify build command: `npm ci --include=dev && npx convex deploy --cmd 'npm run build'`
|
Netlify build command: `npm ci --include=dev && npx convex deploy --cmd 'npm run build'`
|
||||||
|
|
||||||
|
## AI assistance
|
||||||
|
|
||||||
|
- Always use Context7 MCP for library/API documentation, code generation, setup or configuration steps
|
||||||
|
- Proactively look up documentation without explicit requests when working with libraries
|
||||||
|
- Use Context7 for up-to-date API references and best practices
|
||||||
|
|
||||||
## Code conventions
|
## Code conventions
|
||||||
|
|
||||||
- TypeScript strict mode
|
- TypeScript strict mode
|
||||||
|
|||||||
@@ -1240,6 +1240,7 @@ Replace example content in:
|
|||||||
| `content/blog/*.md` | Blog posts |
|
| `content/blog/*.md` | Blog posts |
|
||||||
| `content/pages/*.md` | Static pages (About, etc.) |
|
| `content/pages/*.md` | Static pages (About, etc.) |
|
||||||
| `content/pages/home.md` | Homepage intro content (slug: `home-intro`, uses blog heading styles) |
|
| `content/pages/home.md` | Homepage intro content (slug: `home-intro`, uses blog heading styles) |
|
||||||
|
| `content/pages/footer.md` | Footer content (slug: `footer`, syncs via markdown, falls back to siteConfig.defaultContent) |
|
||||||
| `public/images/logo.svg` | Site logo |
|
| `public/images/logo.svg` | Site logo |
|
||||||
| `public/images/og-default.svg` | Default social share image |
|
| `public/images/og-default.svg` | Default social share image |
|
||||||
| `public/images/logos/*.svg` | Logo gallery images |
|
| `public/images/logos/*.svg` | Logo gallery images |
|
||||||
|
|||||||
9
TASK.md
9
TASK.md
@@ -7,10 +7,17 @@
|
|||||||
|
|
||||||
## Current Status
|
## Current Status
|
||||||
|
|
||||||
v2.1.0 ready. CLAUDE.md and Claude skills documentation complete. Created CLAUDE.md in root for Claude Code instructions, .claude/skills/ directory with three focused skill files (frontmatter.md, convex.md, sync.md), and updated sync-discovery-files.ts to automatically update CLAUDE.md during sync. Documentation updated in files.md, changelog.md, changelog-page.md, and TASK.md.
|
v2.2.0 ready. Footer content via markdown page complete. Created `content/pages/footer.md` for managing footer content via markdown sync. Footer content syncs with `npm run sync` without redeploy needed. Falls back to `siteConfig.footer.defaultContent` when page not found. Documentation updated in files.md, changelog.md, changelog-page.md, FORK_CONFIG.md, docs.md, setup-guide.md, and TASK.md.
|
||||||
|
|
||||||
## Completed
|
## Completed
|
||||||
|
|
||||||
|
- [x] Footer content via markdown page (footer.md)
|
||||||
|
- [x] Created `content/pages/footer.md` for managing footer content via markdown sync
|
||||||
|
- [x] Footer content syncs with `npm run sync` without redeploy needed
|
||||||
|
- [x] Falls back to `siteConfig.footer.defaultContent` when page not found
|
||||||
|
- [x] Updated Home.tsx and Blog.tsx to fetch footer page by slug
|
||||||
|
- [x] Updated files.md, changelog.md, changelog-page.md, FORK_CONFIG.md with documentation
|
||||||
|
|
||||||
- [x] CLAUDE.md and Claude skills documentation
|
- [x] CLAUDE.md and Claude skills documentation
|
||||||
- [x] Created CLAUDE.md in root with project instructions for Claude Code
|
- [x] Created CLAUDE.md in root with project instructions for Claude Code
|
||||||
- [x] Created .claude/skills/ directory with three focused skill files
|
- [x] Created .claude/skills/ directory with three focused skill files
|
||||||
|
|||||||
24
changelog.md
24
changelog.md
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## [2.2.0] - 2025-12-30
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Footer content via markdown page
|
||||||
|
- New `content/pages/footer.md` for managing footer content via markdown sync
|
||||||
|
- Footer content syncs with `npm run sync` without redeploy needed
|
||||||
|
- Edit footer text, links, and formatting through markdown instead of code
|
||||||
|
- Falls back to `siteConfig.footer.defaultContent` when page not found
|
||||||
|
- Set `showInNav: false` to hide from navigation (page remains accessible via direct URL)
|
||||||
|
- Supports full markdown including links, paragraphs, and line breaks
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- `src/pages/Home.tsx`: Fetches footer page by slug "footer" and passes content to Footer component
|
||||||
|
- `src/pages/Blog.tsx`: Fetches footer page by slug "footer" and passes content to Footer component
|
||||||
|
- Footer component now prioritizes page content over siteConfig.defaultContent
|
||||||
|
|
||||||
|
### Technical
|
||||||
|
|
||||||
|
- New file: `content/pages/footer.md` with frontmatter (slug: "footer", showInNav: false)
|
||||||
|
- Uses existing `api.pages.getPageBySlug` query to fetch footer content
|
||||||
|
- Pattern matches `home-intro` page for consistent content management
|
||||||
|
|
||||||
## [2.1.0] - 2025-12-30
|
## [2.1.0] - 2025-12-30
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
published: true
|
|
||||||
unlisted: true
|
|
||||||
@@ -12,8 +12,6 @@ blogFeatured: false
|
|||||||
aiChat: false
|
aiChat: false
|
||||||
image: /images/1225-changelog.png
|
image: /images/1225-changelog.png
|
||||||
excerpt: "Thank you for the stars, forks, and feedback. More AI-first publishing features are coming."
|
excerpt: "Thank you for the stars, forks, and feedback. More AI-first publishing features are coming."
|
||||||
authorName: "Wayne Sutton"
|
|
||||||
authorImage: "/images/authors/markdown.png"
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Happy holidays and thank you
|
# Happy holidays and thank you
|
||||||
|
|||||||
@@ -2,15 +2,17 @@
|
|||||||
title: "How I added WorkOS to my Convex app with Cursor"
|
title: "How I added WorkOS to my Convex app with Cursor"
|
||||||
description: "A timeline of adding WorkOS AuthKit authentication to my markdown blog dashboard using Cursor, prompt engineering, and vibe coding. From PRD import to published feature."
|
description: "A timeline of adding WorkOS AuthKit authentication to my markdown blog dashboard using Cursor, prompt engineering, and vibe coding. From PRD import to published feature."
|
||||||
date: "2025-12-30"
|
date: "2025-12-30"
|
||||||
slug: "how-i-added-workos-with-cursor"
|
slug: "workos-with-convex-cursor"
|
||||||
tags: ["cursor", "workos", "convex", "prompt-engineering", "ai-coding"]
|
tags: ["cursor", "workos", "convex", "prompt-engineering", "ai-coding"]
|
||||||
readTime: "8 min read"
|
readTime: "8 min read"
|
||||||
featured: false
|
featured: false
|
||||||
|
newsletter: false
|
||||||
featuredOrder: 5
|
featuredOrder: 5
|
||||||
published: true
|
published: true
|
||||||
unlisted: true
|
unlisted: true
|
||||||
layout: "sidebar"
|
layout: "sidebar"
|
||||||
excerpt: "How I used Cursor, prompt engineering, and Claude to add WorkOS authentication to my Convex dashboard. A real timeline from PRD import to published feature."
|
excerpt: "How I used Cursor, prompt engineering, and Claude to add WorkOS authentication to my Convex dashboard. A real timeline from PRD import to published feature."
|
||||||
|
authorName: "Wayne Sutton"
|
||||||
---
|
---
|
||||||
|
|
||||||
# How I added WorkOS to my Convex app with Cursor
|
# How I added WorkOS to my Convex app with Cursor
|
||||||
|
|||||||
@@ -1085,6 +1085,8 @@ Pages appear automatically in the navigation when published.
|
|||||||
|
|
||||||
**Home intro content:** Create `content/pages/home.md` (slug: `home-intro`) to sync homepage intro text from markdown. Headings (h1-h6) use blog post styling (`blog-h1` through `blog-h6`) with clickable anchor links. Lists, blockquotes, horizontal rules, and links also use blog styling for consistent typography. Set `textAlign: "left"`, `"center"`, or `"right"` to control alignment. Run `npm run sync` to update homepage text instantly without redeploying. Falls back to `siteConfig.bio` if `home-intro` page not found.
|
**Home intro content:** Create `content/pages/home.md` (slug: `home-intro`) to sync homepage intro text from markdown. Headings (h1-h6) use blog post styling (`blog-h1` through `blog-h6`) with clickable anchor links. Lists, blockquotes, horizontal rules, and links also use blog styling for consistent typography. Set `textAlign: "left"`, `"center"`, or `"right"` to control alignment. Run `npm run sync` to update homepage text instantly without redeploying. Falls back to `siteConfig.bio` if `home-intro` page not found.
|
||||||
|
|
||||||
|
**Footer content via markdown:** Create `content/pages/footer.md` (slug: `footer`) to manage footer content via markdown sync instead of hardcoding in siteConfig.ts. Run `npm run sync` to update footer text instantly without touching code. Supports full markdown including links, paragraphs, and line breaks. Falls back to `siteConfig.footer.defaultContent` if page not found.
|
||||||
|
|
||||||
**Sidebar layout:** Add `layout: "sidebar"` to any post or page frontmatter to enable a docs-style layout with a table of contents sidebar. The sidebar extracts headings (H1, H2, H3) automatically and provides smooth scroll navigation. Only appears if headings exist in the content.
|
**Sidebar layout:** Add `layout: "sidebar"` to any post or page frontmatter to enable a docs-style layout with a table of contents sidebar. The sidebar extracts headings (H1, H2, H3) automatically and provides smooth scroll navigation. Only appears if headings exist in the content.
|
||||||
|
|
||||||
**Right sidebar:** When enabled in `siteConfig.rightSidebar.enabled`, posts and pages can display a right sidebar containing the CopyPageDropdown at 1135px+ viewport width. Add `rightSidebar: true` to frontmatter to enable. Without this field, pages render normally with CopyPageDropdown in the nav bar. When enabled, CopyPageDropdown moves from the navigation bar to the right sidebar on wide screens. The right sidebar is hidden below 1135px, and CopyPageDropdown returns to the nav bar automatically.
|
**Right sidebar:** When enabled in `siteConfig.rightSidebar.enabled`, posts and pages can display a right sidebar containing the CopyPageDropdown at 1135px+ viewport width. Add `rightSidebar: true` to frontmatter to enable. Without this field, pages render normally with CopyPageDropdown in the nav bar. When enabled, CopyPageDropdown moves from the navigation bar to the right sidebar on wide screens. The right sidebar is hidden below 1135px, and CopyPageDropdown returns to the nav bar automatically.
|
||||||
@@ -1093,7 +1095,7 @@ Pages appear automatically in the navigation when published.
|
|||||||
|
|
||||||
**Image lightbox:** Images in blog posts and pages automatically open in a full-screen lightbox when clicked (if enabled in `siteConfig.imageLightbox.enabled`). This allows readers to view images at full size. The lightbox can be closed by clicking outside the image, pressing Escape, or clicking the close button. To disable this feature, set `imageLightbox.enabled: false` in `src/config/siteConfig.ts`.
|
**Image lightbox:** Images in blog posts and pages automatically open in a full-screen lightbox when clicked (if enabled in `siteConfig.imageLightbox.enabled`). This allows readers to view images at full size. The lightbox can be closed by clicking outside the image, pressing Escape, or clicking the close button. To disable this feature, set `imageLightbox.enabled: false` in `src/config/siteConfig.ts`.
|
||||||
|
|
||||||
**Footer:** Footer content can be set in frontmatter (`footer` field) or use `siteConfig.footer.defaultContent`. Control visibility globally via `siteConfig.footer.enabled` and per-page via `showFooter: true/false` frontmatter.
|
**Footer:** Footer content can be managed three ways: (1) Create `content/pages/footer.md` to sync footer content via markdown (recommended), (2) set in frontmatter `footer` field for per-page overrides, or (3) use `siteConfig.footer.defaultContent` for static content. The markdown page takes priority over siteConfig when present. Control visibility globally via `siteConfig.footer.enabled` and per-page via `showFooter: true/false` frontmatter.
|
||||||
|
|
||||||
**Social footer:** Display social icons and copyright below the main footer. Configure via `siteConfig.socialFooter`. Control visibility per-page via `showSocialFooter: true/false` frontmatter.
|
**Social footer:** Display social icons and copyright below the main footer. Configure via `siteConfig.socialFooter`. Control visibility per-page via `showSocialFooter: true/false` frontmatter.
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,29 @@ layout: "sidebar"
|
|||||||
All notable changes to this project.
|
All notable changes to this project.
|
||||||

|

|
||||||
|
|
||||||
|
## v2.2.0
|
||||||
|
|
||||||
|
Released December 30, 2025
|
||||||
|
|
||||||
|
**Footer content via markdown page**
|
||||||
|
|
||||||
|
- New `content/pages/footer.md` for managing footer content via markdown sync
|
||||||
|
- Footer content syncs with `npm run sync` without redeploy needed
|
||||||
|
- Edit footer text, links, and formatting through markdown instead of code
|
||||||
|
- Falls back to `siteConfig.footer.defaultContent` when page not found
|
||||||
|
- Set `showInNav: false` to hide from navigation (page remains accessible via direct URL)
|
||||||
|
- Supports full markdown including links, paragraphs, and line breaks
|
||||||
|
|
||||||
|
**Technical details:**
|
||||||
|
|
||||||
|
- New file: `content/pages/footer.md` with frontmatter (slug: "footer", showInNav: false)
|
||||||
|
- Updated: `src/pages/Home.tsx` to fetch footer page by slug "footer"
|
||||||
|
- Updated: `src/pages/Blog.tsx` to fetch footer page by slug "footer"
|
||||||
|
- Footer component now prioritizes page content over siteConfig.defaultContent
|
||||||
|
- Pattern matches `home-intro` page 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
|
## v2.1.0
|
||||||
|
|
||||||
Released December 30, 2025
|
Released December 30, 2025
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ order: 1
|
|||||||
Content here...
|
Content here...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Frontmatter options
|
||||||
|
|
||||||
| Field | Required | Description |
|
| Field | Required | Description |
|
||||||
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `title` | Yes | Nav link text |
|
| `title` | Yes | Nav link text |
|
||||||
@@ -216,6 +218,38 @@ Your homepage intro text here.
|
|||||||
|
|
||||||
**Fallback:** If `home-intro` page is not found, the homepage falls back to `siteConfig.bio` text.
|
**Fallback:** If `home-intro` page is not found, the homepage falls back to `siteConfig.bio` text.
|
||||||
|
|
||||||
|
### Footer content
|
||||||
|
|
||||||
|
The footer content can be synced from markdown via `content/pages/footer.md` (slug: `footer`). This allows you to update footer text without touching code.
|
||||||
|
|
||||||
|
**Create footer content:**
|
||||||
|
|
||||||
|
1. Create `content/pages/footer.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
title: "Footer"
|
||||||
|
slug: "footer"
|
||||||
|
published: true
|
||||||
|
showInNav: false
|
||||||
|
order: -1
|
||||||
|
---
|
||||||
|
|
||||||
|
Built with [Convex](https://convex.dev) for real-time sync and deployed on [Netlify](https://netlify.com).
|
||||||
|
|
||||||
|
Created by [Your Name](https://x.com/yourhandle). Follow on [Twitter/X](https://x.com/yourhandle) and [GitHub](https://github.com/yourusername).
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run `npm run sync` to sync to Convex
|
||||||
|
|
||||||
|
3. Footer content appears on homepage and blog page instantly (no rebuild needed)
|
||||||
|
|
||||||
|
**Markdown support:** Footer content supports full markdown including links, paragraphs, line breaks, and images. External links automatically open in new tabs.
|
||||||
|
|
||||||
|
**Fallback:** If `footer` page is not found, the footer falls back to `siteConfig.footer.defaultContent`.
|
||||||
|
|
||||||
|
**Relationship with siteConfig:** The `content/pages/footer.md` page takes priority over `siteConfig.footer.defaultContent` when present. Use the markdown page for dynamic content that changes frequently, or keep using siteConfig for static footer content.
|
||||||
|
|
||||||
### Sidebar layout
|
### Sidebar layout
|
||||||
|
|
||||||
Posts and pages can use a docs-style layout with a table of contents sidebar. Add `layout: "sidebar"` to the frontmatter:
|
Posts and pages can use a docs-style layout with a table of contents sidebar. Add `layout: "sidebar"` to the frontmatter:
|
||||||
|
|||||||
11
content/pages/footer.md
Normal file
11
content/pages/footer.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
title: "Footer"
|
||||||
|
slug: "footer"
|
||||||
|
published: true
|
||||||
|
showInNav: false
|
||||||
|
order: -1
|
||||||
|
---
|
||||||
|
|
||||||
|
Built with [Convex](https://convex.dev) for real-time sync and deployed on [Netlify](https://netlify.com). Read the [project on GitHub](https://github.com/waynesutton/markdown-site) to fork and deploy your own. View [real-time site stats](/stats).
|
||||||
|
|
||||||
|
Created by [Wayne](https://x.com/waynesutton) with Convex, Cursor, and Claude Opus 4.5. Follow on [Twitter/X](https://x.com/waynesutton), [LinkedIn](https://www.linkedin.com/in/waynesutton/), and [GitHub](https://github.com/waynesutton). This project is licensed under the MIT [License](https://github.com/waynesutton/markdown-site?tab=MIT-1-ov-file).
|
||||||
1
files.md
1
files.md
@@ -177,6 +177,7 @@ Markdown files for static pages like About, Projects, Contact, Changelog.
|
|||||||
|
|
||||||
**Special pages:**
|
**Special pages:**
|
||||||
- `home.md` (slug: `home-intro`): Homepage intro/bio content. Set `showInNav: false` to hide from navigation. Content syncs with `npm run sync` and displays on the homepage without redeploy. Headings (h1-h6) use blog post styling (`blog-h1` through `blog-h6`) with clickable anchor links. Lists, blockquotes, horizontal rules, and links also use blog styling classes for consistent typography. Use `textAlign` frontmatter field to control alignment (left/center/right, default: left). Falls back to `siteConfig.bio` if page not found or while loading.
|
- `home.md` (slug: `home-intro`): Homepage intro/bio content. Set `showInNav: false` to hide from navigation. Content syncs with `npm run sync` and displays on the homepage without redeploy. Headings (h1-h6) use blog post styling (`blog-h1` through `blog-h6`) with clickable anchor links. Lists, blockquotes, horizontal rules, and links also use blog styling classes for consistent typography. Use `textAlign` frontmatter field to control alignment (left/center/right, default: left). Falls back to `siteConfig.bio` if page not found or while loading.
|
||||||
|
- `footer.md` (slug: `footer`): Footer content managed via markdown sync. Set `showInNav: false` to hide from navigation. Content syncs with `npm run sync` and displays in the footer component without redeploy. Supports full markdown including links, paragraphs, and line breaks. Falls back to `siteConfig.footer.defaultContent` if page not found or while loading. This allows editing footer content without touching code.
|
||||||
|
|
||||||
| Field | Description |
|
| Field | Description |
|
||||||
| --------------- | ----------------------------------------------------------------------- |
|
| --------------- | ----------------------------------------------------------------------- |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# llms.txt - Information for AI assistants and LLMs
|
# llms.txt - Information for AI assistants and LLMs
|
||||||
# Learn more: https://llmstxt.org/
|
# Learn more: https://llmstxt.org/
|
||||||
# Last updated: 2025-12-30T20:03:38.736Z
|
# Last updated: 2025-12-30T23:27:44.147Z
|
||||||
|
|
||||||
> Your content is instantly available to browsers, LLMs, and AI agents.
|
> Your content is instantly available to browsers, LLMs, and AI agents.
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
An open-source publishing framework built for AI agents and developers to ship websites, docs, or blogs.. Write markdown, sync from the terminal. Your content is instantly available to browsers, LLMs, and AI agents. Built on Convex and Netlify.
|
An open-source publishing framework built for AI agents and developers to ship websites, docs, or blogs.. Write markdown, sync from the terminal. Your content is instantly available to browsers, LLMs, and AI agents. Built on Convex and Netlify.
|
||||||
|
|||||||
@@ -2,12 +2,35 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
All notable changes to this project.
|
All notable changes to this project.
|
||||||

|

|
||||||
|
|
||||||
|
## v2.2.0
|
||||||
|
|
||||||
|
Released December 30, 2025
|
||||||
|
|
||||||
|
**Footer content via markdown page**
|
||||||
|
|
||||||
|
- New `content/pages/footer.md` for managing footer content via markdown sync
|
||||||
|
- Footer content syncs with `npm run sync` without redeploy needed
|
||||||
|
- Edit footer text, links, and formatting through markdown instead of code
|
||||||
|
- Falls back to `siteConfig.footer.defaultContent` when page not found
|
||||||
|
- Set `showInNav: false` to hide from navigation (page remains accessible via direct URL)
|
||||||
|
- Supports full markdown including links, paragraphs, and line breaks
|
||||||
|
|
||||||
|
**Technical details:**
|
||||||
|
|
||||||
|
- New file: `content/pages/footer.md` with frontmatter (slug: "footer", showInNav: false)
|
||||||
|
- Updated: `src/pages/Home.tsx` to fetch footer page by slug "footer"
|
||||||
|
- Updated: `src/pages/Blog.tsx` to fetch footer page by slug "footer"
|
||||||
|
- Footer component now prioritizes page content over siteConfig.defaultContent
|
||||||
|
- Pattern matches `home-intro` page 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
|
## v2.1.0
|
||||||
|
|
||||||
Released December 30, 2025
|
Released December 30, 2025
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
You found the contact page. Nice
|
You found the contact page. Nice
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
@@ -143,6 +143,8 @@ order: 1
|
|||||||
Content here...
|
Content here...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Frontmatter options
|
||||||
|
|
||||||
| Field | Required | Description |
|
| Field | Required | Description |
|
||||||
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
| `title` | Yes | Nav link text |
|
| `title` | Yes | Nav link text |
|
||||||
@@ -213,6 +215,38 @@ Your homepage intro text here.
|
|||||||
|
|
||||||
**Fallback:** If `home-intro` page is not found, the homepage falls back to `siteConfig.bio` text.
|
**Fallback:** If `home-intro` page is not found, the homepage falls back to `siteConfig.bio` text.
|
||||||
|
|
||||||
|
### Footer content
|
||||||
|
|
||||||
|
The footer content can be synced from markdown via `content/pages/footer.md` (slug: `footer`). This allows you to update footer text without touching code.
|
||||||
|
|
||||||
|
**Create footer content:**
|
||||||
|
|
||||||
|
1. Create `content/pages/footer.md`:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
title: "Footer"
|
||||||
|
slug: "footer"
|
||||||
|
published: true
|
||||||
|
showInNav: false
|
||||||
|
order: -1
|
||||||
|
---
|
||||||
|
|
||||||
|
Built with [Convex](https://convex.dev) for real-time sync and deployed on [Netlify](https://netlify.com).
|
||||||
|
|
||||||
|
Created by [Your Name](https://x.com/yourhandle). Follow on [Twitter/X](https://x.com/yourhandle) and [GitHub](https://github.com/yourusername).
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run `npm run sync` to sync to Convex
|
||||||
|
|
||||||
|
3. Footer content appears on homepage and blog page instantly (no rebuild needed)
|
||||||
|
|
||||||
|
**Markdown support:** Footer content supports full markdown including links, paragraphs, line breaks, and images. External links automatically open in new tabs.
|
||||||
|
|
||||||
|
**Fallback:** If `footer` page is not found, the footer falls back to `siteConfig.footer.defaultContent`.
|
||||||
|
|
||||||
|
**Relationship with siteConfig:** The `content/pages/footer.md` page takes priority over `siteConfig.footer.defaultContent` when present. Use the markdown page for dynamic content that changes frequently, or keep using siteConfig for static footer content.
|
||||||
|
|
||||||
### Sidebar layout
|
### Sidebar layout
|
||||||
|
|
||||||
Posts and pages can use a docs-style layout with a table of contents sidebar. Add `layout: "sidebar"` to the frontmatter:
|
Posts and pages can use a docs-style layout with a table of contents sidebar. Add `layout: "sidebar"` to the frontmatter:
|
||||||
|
|||||||
10
public/raw/footer.md
Normal file
10
public/raw/footer.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Footer
|
||||||
|
|
||||||
|
---
|
||||||
|
Type: page
|
||||||
|
Date: 2025-12-31
|
||||||
|
---
|
||||||
|
|
||||||
|
Built with [Convex](https://convex.dev) for real-time sync and deployed on [Netlify](https://netlify.com). Read the [project on GitHub](https://github.com/waynesutton/markdown-site) to fork and deploy your own. View [real-time site stats](/stats).
|
||||||
|
|
||||||
|
Created by [Wayne](https://x.com/waynesutton) with Convex, Cursor, and Claude Opus 4.5. Follow on [Twitter/X](https://x.com/waynesutton), [LinkedIn](https://www.linkedin.com/in/waynesutton/), and [GitHub](https://github.com/waynesutton). This project is licensed under the MIT [License](https://github.com/waynesutton/markdown-site?tab=MIT-1-ov-file).
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
An open-source publishing framework built for AI agents and developers to ship **[docs](/docs)**, or **[blogs](/blog)** or **[websites](/)**.
|
An open-source publishing framework built for AI agents and developers to ship **[docs](/docs)**, or **[blogs](/blog)** or **[websites](/)**.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ This is the homepage index of all published content.
|
|||||||
|
|
||||||
## Blog Posts (18)
|
## Blog Posts (18)
|
||||||
|
|
||||||
- **[How I added WorkOS to my Convex app with Cursor](/raw/how-i-added-workos-with-cursor.md)** - A timeline of adding WorkOS AuthKit authentication to my markdown blog dashboard using Cursor, prompt engineering, and vibe coding. From PRD import to published feature.
|
- **[How I added WorkOS to my Convex app with Cursor](/raw/workos-with-convex-cursor.md)** - A timeline of adding WorkOS AuthKit authentication to my markdown blog dashboard using Cursor, prompt engineering, and vibe coding. From PRD import to published feature.
|
||||||
- Date: 2025-12-30 | Reading time: 8 min read | Tags: cursor, workos, convex, prompt-engineering, ai-coding
|
- Date: 2025-12-30 | Reading time: 8 min read | Tags: cursor, workos, convex, prompt-engineering, ai-coding
|
||||||
- **[How to setup WorkOS with Markdown Sync](/raw/how-to-setup-workos.md)** - Step-by-step guide to configure WorkOS AuthKit authentication for your markdown blog dashboard. WorkOS is optional and can be enabled in siteConfig.ts.
|
- **[How to setup WorkOS with Markdown Sync](/raw/how-to-setup-workos.md)** - 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 | Reading time: 10 min read | Tags: workos, authentication, tutorial, dashboard
|
- Date: 2025-12-29 | Reading time: 10 min read | Tags: workos, authentication, tutorial, dashboard
|
||||||
@@ -41,8 +41,9 @@ This is the homepage index of all published content.
|
|||||||
- **[Using Images in Blog Posts](/raw/using-images-in-posts.md)** - Learn how to add header images, inline images, and Open Graph images to your markdown posts.
|
- **[Using Images in Blog Posts](/raw/using-images-in-posts.md)** - Learn how to add header images, inline images, and Open Graph images to your markdown posts.
|
||||||
- Date: 2025-12-14 | Reading time: 4 min read | Tags: images, tutorial, markdown, open-graph
|
- Date: 2025-12-14 | Reading time: 4 min read | Tags: images, tutorial, markdown, open-graph
|
||||||
|
|
||||||
## Pages (7)
|
## Pages (8)
|
||||||
|
|
||||||
|
- **[Footer](/raw/footer.md)**
|
||||||
- **[Home Intro](/raw/home-intro.md)**
|
- **[Home Intro](/raw/home-intro.md)**
|
||||||
- **[Docs](/raw/docs.md)**
|
- **[Docs](/raw/docs.md)**
|
||||||
- **[About](/raw/about.md)** - An open-source publishing framework built for AI agents and developers to ship websites, docs, or blogs..
|
- **[About](/raw/about.md)** - An open-source publishing framework built for AI agents and developers to ship websites, docs, or blogs..
|
||||||
@@ -53,6 +54,6 @@ This is the homepage index of all published content.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Total Content:** 18 posts, 7 pages
|
**Total Content:** 18 posts, 8 pages
|
||||||
|
|
||||||
All content is available as raw markdown files at `/raw/{slug}.md`
|
All content is available as raw markdown files at `/raw/{slug}.md`
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
# Newsletter Demo Page
|
# Newsletter Demo Page
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
Type: page
|
Type: page
|
||||||
Date: 2025-12-30
|
Date: 2025-12-31
|
||||||
---
|
---
|
||||||
|
|
||||||
This markdown framework is open source and built to be extended. Here is what ships out of the box.
|
This markdown framework is open source and built to be extended. Here is what ships out of the box.
|
||||||
|
|||||||
@@ -1078,6 +1078,8 @@ Pages appear automatically in the navigation when published.
|
|||||||
|
|
||||||
**Home intro content:** Create `content/pages/home.md` (slug: `home-intro`) to sync homepage intro text from markdown. Headings (h1-h6) use blog post styling (`blog-h1` through `blog-h6`) with clickable anchor links. Lists, blockquotes, horizontal rules, and links also use blog styling for consistent typography. Set `textAlign: "left"`, `"center"`, or `"right"` to control alignment. Run `npm run sync` to update homepage text instantly without redeploying. Falls back to `siteConfig.bio` if `home-intro` page not found.
|
**Home intro content:** Create `content/pages/home.md` (slug: `home-intro`) to sync homepage intro text from markdown. Headings (h1-h6) use blog post styling (`blog-h1` through `blog-h6`) with clickable anchor links. Lists, blockquotes, horizontal rules, and links also use blog styling for consistent typography. Set `textAlign: "left"`, `"center"`, or `"right"` to control alignment. Run `npm run sync` to update homepage text instantly without redeploying. Falls back to `siteConfig.bio` if `home-intro` page not found.
|
||||||
|
|
||||||
|
**Footer content via markdown:** Create `content/pages/footer.md` (slug: `footer`) to manage footer content via markdown sync instead of hardcoding in siteConfig.ts. Run `npm run sync` to update footer text instantly without touching code. Supports full markdown including links, paragraphs, and line breaks. Falls back to `siteConfig.footer.defaultContent` if page not found.
|
||||||
|
|
||||||
**Sidebar layout:** Add `layout: "sidebar"` to any post or page frontmatter to enable a docs-style layout with a table of contents sidebar. The sidebar extracts headings (H1, H2, H3) automatically and provides smooth scroll navigation. Only appears if headings exist in the content.
|
**Sidebar layout:** Add `layout: "sidebar"` to any post or page frontmatter to enable a docs-style layout with a table of contents sidebar. The sidebar extracts headings (H1, H2, H3) automatically and provides smooth scroll navigation. Only appears if headings exist in the content.
|
||||||
|
|
||||||
**Right sidebar:** When enabled in `siteConfig.rightSidebar.enabled`, posts and pages can display a right sidebar containing the CopyPageDropdown at 1135px+ viewport width. Add `rightSidebar: true` to frontmatter to enable. Without this field, pages render normally with CopyPageDropdown in the nav bar. When enabled, CopyPageDropdown moves from the navigation bar to the right sidebar on wide screens. The right sidebar is hidden below 1135px, and CopyPageDropdown returns to the nav bar automatically.
|
**Right sidebar:** When enabled in `siteConfig.rightSidebar.enabled`, posts and pages can display a right sidebar containing the CopyPageDropdown at 1135px+ viewport width. Add `rightSidebar: true` to frontmatter to enable. Without this field, pages render normally with CopyPageDropdown in the nav bar. When enabled, CopyPageDropdown moves from the navigation bar to the right sidebar on wide screens. The right sidebar is hidden below 1135px, and CopyPageDropdown returns to the nav bar automatically.
|
||||||
@@ -1086,7 +1088,7 @@ Pages appear automatically in the navigation when published.
|
|||||||
|
|
||||||
**Image lightbox:** Images in blog posts and pages automatically open in a full-screen lightbox when clicked (if enabled in `siteConfig.imageLightbox.enabled`). This allows readers to view images at full size. The lightbox can be closed by clicking outside the image, pressing Escape, or clicking the close button. To disable this feature, set `imageLightbox.enabled: false` in `src/config/siteConfig.ts`.
|
**Image lightbox:** Images in blog posts and pages automatically open in a full-screen lightbox when clicked (if enabled in `siteConfig.imageLightbox.enabled`). This allows readers to view images at full size. The lightbox can be closed by clicking outside the image, pressing Escape, or clicking the close button. To disable this feature, set `imageLightbox.enabled: false` in `src/config/siteConfig.ts`.
|
||||||
|
|
||||||
**Footer:** Footer content can be set in frontmatter (`footer` field) or use `siteConfig.footer.defaultContent`. Control visibility globally via `siteConfig.footer.enabled` and per-page via `showFooter: true/false` frontmatter.
|
**Footer:** Footer content can be managed three ways: (1) Create `content/pages/footer.md` to sync footer content via markdown (recommended), (2) set in frontmatter `footer` field for per-page overrides, or (3) use `siteConfig.footer.defaultContent` for static content. The markdown page takes priority over siteConfig when present. Control visibility globally via `siteConfig.footer.enabled` and per-page via `showFooter: true/false` frontmatter.
|
||||||
|
|
||||||
**Social footer:** Display social icons and copyright below the main footer. Configure via `siteConfig.socialFooter`. Control visibility per-page via `showSocialFooter: true/false` frontmatter.
|
**Social footer:** Display social icons and copyright below the main footer. Configure via `siteConfig.socialFooter`. Control visibility per-page via `showSocialFooter: true/false` frontmatter.
|
||||||
|
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ export const siteConfig: SiteConfig = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Footer configuration
|
// Footer configuration
|
||||||
// Footer content can be set in frontmatter (footer field) or use defaultContent here
|
// Footer content is loaded from content/pages/footer.md (synced via npm run sync)
|
||||||
// Use showFooter: false in frontmatter to hide footer on specific posts/pages
|
// Use showFooter: false in frontmatter to hide footer on specific posts/pages
|
||||||
footer: {
|
footer: {
|
||||||
enabled: true, // Global toggle for footer
|
enabled: true, // Global toggle for footer
|
||||||
@@ -499,10 +499,8 @@ export const siteConfig: SiteConfig = {
|
|||||||
showOnPosts: true, // Default: show footer on blog posts (override with frontmatter)
|
showOnPosts: true, // Default: show footer on blog posts (override with frontmatter)
|
||||||
showOnPages: true, // Default: show footer on static pages (override with frontmatter)
|
showOnPages: true, // Default: show footer on static pages (override with frontmatter)
|
||||||
showOnBlogPage: true, // Show footer on /blog page
|
showOnBlogPage: true, // Show footer on /blog page
|
||||||
// Default footer markdown (used when frontmatter footer field is not provided)
|
// Default footer markdown (fallback if footer.md doesn't exist - edit content/pages/footer.md instead)
|
||||||
defaultContent: `Built with [Convex](https://convex.dev) for real-time sync and deployed on [Netlify](https://netlify.com). Read the [project on GitHub](https://github.com/waynesutton/markdown-site) to fork and deploy your own. View [real-time site stats](/stats).
|
defaultContent: undefined,
|
||||||
|
|
||||||
Created by [Wayne](https://x.com/waynesutton) with Convex, Cursor, and Claude Opus 4.5. Follow on [Twitter/X](https://x.com/waynesutton), [LinkedIn](https://www.linkedin.com/in/waynesutton/), and [GitHub](https://github.com/waynesutton). This project is licensed under the MIT [License](https://github.com/waynesutton/markdown-site?tab=MIT-1-ov-file).`,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Homepage configuration
|
// Homepage configuration
|
||||||
@@ -577,6 +575,7 @@ Created by [Wayne](https://x.com/waynesutton) with Convex, Cursor, and Claude Op
|
|||||||
},
|
},
|
||||||
{ platform: "twitter", url: "https://x.com/waynesutton" },
|
{ platform: "twitter", url: "https://x.com/waynesutton" },
|
||||||
{ platform: "linkedin", url: "https://www.linkedin.com/in/waynesutton/" },
|
{ platform: "linkedin", url: "https://www.linkedin.com/in/waynesutton/" },
|
||||||
|
{ platform: "discord", url: "https://www.convex.dev/community/" },
|
||||||
],
|
],
|
||||||
copyright: {
|
copyright: {
|
||||||
siteName: "MarkDown Sync is open-source", // Update with your site/company name
|
siteName: "MarkDown Sync is open-source", // Update with your site/company name
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ export default function Blog() {
|
|||||||
// Fetch all blog featured posts for hero + featured row
|
// Fetch all blog featured posts for hero + featured row
|
||||||
const blogFeaturedPosts = useQuery(api.posts.getBlogFeaturedPosts);
|
const blogFeaturedPosts = useQuery(api.posts.getBlogFeaturedPosts);
|
||||||
|
|
||||||
|
// Fetch footer content from Convex (synced via markdown)
|
||||||
|
const footerPage = useQuery(api.pages.getPageBySlug, { slug: "footer" });
|
||||||
|
|
||||||
// State for view mode toggle (list or cards)
|
// State for view mode toggle (list or cards)
|
||||||
const [viewMode, setViewMode] = useState<"list" | "cards">(
|
const [viewMode, setViewMode] = useState<"list" | "cards">(
|
||||||
siteConfig.blogPage.viewMode,
|
siteConfig.blogPage.viewMode,
|
||||||
@@ -218,7 +221,7 @@ export default function Blog() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Footer section */}
|
{/* Footer section */}
|
||||||
{showFooter && <Footer />}
|
{showFooter && <Footer content={footerPage?.content} />}
|
||||||
|
|
||||||
{/* Social footer section */}
|
{/* Social footer section */}
|
||||||
{siteConfig.socialFooter?.enabled && siteConfig.socialFooter.showOnBlogPage && (
|
{siteConfig.socialFooter?.enabled && siteConfig.socialFooter.showOnBlogPage && (
|
||||||
|
|||||||
@@ -4092,6 +4092,11 @@ export default siteConfig;
|
|||||||
<span>Show on pages</span>
|
<span>Show on pages</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<p className="config-field-note" style={{ marginTop: "0.75rem" }}>
|
||||||
|
Footer content is managed via{" "}
|
||||||
|
<code>content/pages/footer.md</code>. Run{" "}
|
||||||
|
<code>npm run sync</code> to update.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* AI Chat Settings */}
|
{/* AI Chat Settings */}
|
||||||
|
|||||||
@@ -100,6 +100,9 @@ export default function Home() {
|
|||||||
// Fetch home intro content from Convex (synced via markdown)
|
// Fetch home intro content from Convex (synced via markdown)
|
||||||
const homeIntro = useQuery(api.pages.getPageBySlug, { slug: "home-intro" });
|
const homeIntro = useQuery(api.pages.getPageBySlug, { slug: "home-intro" });
|
||||||
|
|
||||||
|
// Fetch footer content from Convex (synced via markdown)
|
||||||
|
const footerPage = useQuery(api.pages.getPageBySlug, { slug: "footer" });
|
||||||
|
|
||||||
// State for view mode toggle (list or cards)
|
// State for view mode toggle (list or cards)
|
||||||
const [viewMode, setViewMode] = useState<"list" | "cards">(
|
const [viewMode, setViewMode] = useState<"list" | "cards">(
|
||||||
siteConfig.featuredViewMode,
|
siteConfig.featuredViewMode,
|
||||||
@@ -408,7 +411,7 @@ export default function Home() {
|
|||||||
|
|
||||||
{/* Footer section */}
|
{/* Footer section */}
|
||||||
{siteConfig.footer.enabled && siteConfig.footer.showOnHomepage && (
|
{siteConfig.footer.enabled && siteConfig.footer.showOnHomepage && (
|
||||||
<Footer content={siteConfig.footer.defaultContent} />
|
<Footer content={footerPage?.content} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Social footer section */}
|
{/* Social footer section */}
|
||||||
|
|||||||
Reference in New Issue
Block a user