mirror of
https://github.com/waynesutton/markdown-site.git
synced 2026-01-12 04:09:14 +00:00
299 lines
9.3 KiB
Markdown
299 lines
9.3 KiB
Markdown
# Content
|
|
|
|
---
|
|
Type: page
|
|
Date: 2026-01-11
|
|
---
|
|
|
|
## 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:
|
|
|
|
```markdown
|
|
---
|
|
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...
|
|
```
|
|
|
|
See the [Frontmatter](/docs-frontmatter) page for all available fields.
|
|
|
|
### Static pages
|
|
|
|
Create files in `content/pages/` with frontmatter:
|
|
|
|
```markdown
|
|
---
|
|
title: "Page Title"
|
|
slug: "url-path"
|
|
published: true
|
|
order: 1
|
|
---
|
|
|
|
Content here...
|
|
```
|
|
|
|
See the [Frontmatter](/docs-frontmatter) page for all available fields.
|
|
|
|
### Home intro content
|
|
|
|
The homepage intro text can be synced from markdown via `content/pages/home.md` (slug: `home-intro`). This allows you to update homepage text without redeploying.
|
|
|
|
**Create home intro:**
|
|
|
|
1. Create `content/pages/home.md`:
|
|
|
|
```markdown
|
|
---
|
|
title: "Home Intro"
|
|
slug: "home-intro"
|
|
published: true
|
|
showInNav: false
|
|
order: -1
|
|
textAlign: "left"
|
|
---
|
|
|
|
Your homepage intro text here.
|
|
|
|
## Features
|
|
|
|
**Feature one** - Description here.
|
|
|
|
**Feature two** - Description here.
|
|
```
|
|
|
|
2. Run `npm run sync` to sync to Convex
|
|
|
|
3. Content appears on homepage instantly (no rebuild needed)
|
|
|
|
**Blog heading styles:** Headings (h1-h6) in home intro content use the same styling as blog posts (`blog-h1` through `blog-h6` classes). Each heading gets an automatic ID and a clickable anchor link (#) that appears on hover. Lists, blockquotes, horizontal rules, and links also use blog styling classes for consistent typography.
|
|
|
|
**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, blog page, and all posts/pages 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`.
|
|
|
|
**Priority order:** Per-post/page frontmatter `footer:` field (custom override) > synced footer.md content > 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
|
|
|
|
Posts and pages can use a docs-style layout with a table of contents sidebar. Add `layout: "sidebar"` to the frontmatter:
|
|
|
|
```markdown
|
|
---
|
|
title: "Documentation"
|
|
slug: "docs"
|
|
published: true
|
|
layout: "sidebar"
|
|
---
|
|
|
|
# Introduction
|
|
|
|
## Section One
|
|
|
|
### Subsection
|
|
|
|
## Section Two
|
|
```
|
|
|
|
**Features:**
|
|
|
|
- Left sidebar displays table of contents extracted from H1, H2, H3 headings
|
|
- Two-column layout: 220px sidebar + flexible content area
|
|
- Sidebar only appears if headings exist in the content
|
|
- Active heading highlighting as you scroll
|
|
- Smooth scroll navigation when clicking TOC links
|
|
- Mobile responsive: stacks to single column below 1024px
|
|
- Works for both blog posts and static pages
|
|
|
|
The sidebar extracts headings automatically from your markdown content. No manual TOC needed.
|
|
|
|
### Right sidebar
|
|
|
|
When enabled in `siteConfig.rightSidebar.enabled`, posts and pages can display a right sidebar containing the CopyPageDropdown at 1135px+ viewport width.
|
|
|
|
**Configuration:**
|
|
|
|
Enable globally in `src/config/siteConfig.ts`:
|
|
|
|
```typescript
|
|
rightSidebar: {
|
|
enabled: true, // Set to false to disable right sidebar globally
|
|
minWidth: 1135, // Minimum viewport width to show sidebar
|
|
},
|
|
```
|
|
|
|
Control per post/page with frontmatter:
|
|
|
|
```markdown
|
|
---
|
|
title: "My Post"
|
|
rightSidebar: true # Enable right sidebar for this post
|
|
---
|
|
```
|
|
|
|
**Features:**
|
|
|
|
- Right sidebar appears at 1135px+ viewport width
|
|
- Contains CopyPageDropdown with all sharing options
|
|
- Three-column layout: left sidebar (TOC), main content, right sidebar
|
|
- CopyPageDropdown automatically moves from nav to right sidebar when enabled
|
|
- Hidden below 1135px breakpoint, CopyPageDropdown returns to nav
|
|
- Per-post/page control via `rightSidebar: true` frontmatter field
|
|
- Opt-in only: right sidebar only appears when explicitly enabled in frontmatter
|
|
|
|
**Use cases:**
|
|
|
|
- Keep CopyPageDropdown accessible on wide screens without cluttering the nav
|
|
- Provide quick access to sharing options while reading long content
|
|
- Works alongside left sidebar TOC for comprehensive navigation
|
|
|
|
**Example for blog post:**
|
|
|
|
```markdown
|
|
---
|
|
title: "My Tutorial"
|
|
description: "A detailed guide"
|
|
date: "2025-01-20"
|
|
slug: "my-tutorial"
|
|
published: true
|
|
tags: ["tutorial"]
|
|
layout: "sidebar"
|
|
---
|
|
|
|
# Introduction
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
## Advanced Topics
|
|
```
|
|
|
|
### How frontmatter works
|
|
|
|
Frontmatter is the YAML metadata at the top of each markdown file between `---` markers. Here is how it flows through the system:
|
|
|
|
**Content directories:**
|
|
|
|
- `content/blog/*.md` contains blog posts with frontmatter
|
|
- `content/pages/*.md` contains static pages with frontmatter
|
|
|
|
**Processing flow:**
|
|
|
|
1. Markdown files in `content/blog/` and `content/pages/` contain YAML frontmatter
|
|
2. `scripts/sync-posts.ts` uses `gray-matter` to parse frontmatter and validate required fields
|
|
3. Parsed data is sent to Convex mutations (`api.posts.syncPostsPublic`, `api.pages.syncPagesPublic`)
|
|
4. `convex/schema.ts` defines the database structure for storing the data
|
|
|
|
**Adding a new frontmatter field:**
|
|
|
|
To add a custom frontmatter field, update these files:
|
|
|
|
1. The interface in `scripts/sync-posts.ts` (`PostFrontmatter` or `PageFrontmatter`)
|
|
2. The parsing logic in `parseMarkdownFile()` or `parsePageFile()` functions
|
|
3. The schema in `convex/schema.ts`
|
|
4. The sync mutation in `convex/posts.ts` or `convex/pages.ts`
|
|
|
|
### Syncing content
|
|
|
|
**Development:**
|
|
|
|
```bash
|
|
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:**
|
|
|
|
```bash
|
|
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 everything together:**
|
|
|
|
```bash
|
|
npm run sync:all # Development: content + discovery
|
|
npm run sync:all:prod # Production: content + discovery
|
|
```
|
|
|
|
### When to sync vs deploy
|
|
|
|
| What you're changing | Command | Timing |
|
|
| -------------------------------- | -------------------------- | ----------------------- |
|
|
| Blog posts in `content/blog/` | `npm run sync` | Instant (no rebuild) |
|
|
| Pages in `content/pages/` | `npm run sync` | Instant (no rebuild) |
|
|
| Featured items (via frontmatter) | `npm run sync` | Instant (no rebuild) |
|
|
| Site config changes | `npm run sync:discovery` | Updates discovery files |
|
|
| Import external URL | `npm run import` then sync | Instant (no rebuild) |
|
|
| Images in `public/images/` | Git commit + push | Requires rebuild |
|
|
| `siteConfig` in `Home.tsx` | Redeploy | Requires rebuild |
|
|
| Logo gallery config | Redeploy | Requires rebuild |
|
|
| React components/styles | Redeploy | Requires rebuild |
|
|
|
|
**Markdown content** syncs instantly to Convex. **Images and source code** require pushing to GitHub for Netlify to rebuild.
|
|
|
|
## Tag pages and related posts
|
|
|
|
Tag pages are available at `/tags/[tag]` for each tag used in your posts. They display all posts with that tag in a list or card view with localStorage persistence for view mode preference.
|
|
|
|
**Related posts:** Individual blog posts show up to 3 related posts in the footer based on shared tags. Posts are sorted by relevance (number of shared tags) then by date. Only appears on blog posts (not static pages).
|
|
|
|
**Tag links:** Tags in post footers link to their respective tag archive pages.
|
|
|
|
## Blog page featured layout
|
|
|
|
Posts can be marked as featured on the blog page using the `blogFeatured` frontmatter field:
|
|
|
|
```yaml
|
|
---
|
|
title: "My Featured Post"
|
|
blogFeatured: true
|
|
---
|
|
```
|
|
|
|
The first `blogFeatured` post displays as a hero card with landscape image, tags, date, title, excerpt, author info, and read more link. Remaining `blogFeatured` posts display in a 2-column featured row with excerpts. Regular (non-featured) posts display in a 3-column grid without excerpts. |