Write in Markdown
YAML frontmatter format for hand-written posts uploaded or published via the CLI.
Write a .md file locally with YAML frontmatter, then save it as a draft with blogizi draft or publish live with blogizi publish. AI coding agents can write the file for you — the CLI only pushes it to Blogizi.
When to use this
- You already write in your editor (VS Code, Obsidian, etc.)
- You version posts in git alongside your repo
- An AI coding agent drafts the markdown and you push via CLI
- Prefer Obsidian? See the Obsidian plugin guide
Frontmatter template
Every post file starts with YAML frontmatter between --- delimiters. The CLI parses these fields and sends them to Blogizi when you publish.
---
title: "How we built our auth flow"
description: "A walkthrough of the auth decisions we made — sessions, OAuth, and what we'd do differently."
keyword: "indie app authentication"
slug: "how-we-built-our-auth-flow"
status: "draft"
date: "2026-07-21"
readingTime: 0
wordCount: 0
---
Your markdown content starts here. Use `##` and `###` for sections — the page already shows the title, so don't open with a heading that just repeats it.Field reference
| Field | Required | Notes |
|---|---|---|
title | Yes | Page title and H1 on your blog |
description | Yes | Meta description for SEO and social cards (~150–160 chars) |
keyword | Yes | Primary SEO keyword for the post |
slug | Yes | URL path — lowercase letters, numbers, and hyphens only (e.g. my-post-title) |
status | No | draft or published — blogizi draft always sets draft; blogizi publish always sets published regardless |
date | No | YYYY-MM-DD — informational / CLI display; does not rewrite publishedAt on already-published posts |
scheduledAt | No | Future publish time. ISO with Z/offset is absolute; naive YYYY-MM-DDTHH:mm uses the project timezone (Settings → General). Future → keeps draft and publishes at that time; omit to leave schedule unchanged; empty/null clears it. CLI equivalent: --scheduled-at / --unschedule. blogizi publish always publishes immediately and cancels any schedule |
readingTime | No | Leave as 0 — recalculated from content on publish |
wordCount | No | Leave as 0 — recalculated from content on publish |
ctaTitle | No | Per-post CTA title — overrides the project branding CTA when ctaTitle, ctaButtonLabel, and ctaButtonUrl are all set |
ctaSubtitle | No | Per-post CTA subtitle (optional even when CTA is shown) |
ctaButtonLabel | No | Per-post CTA button label |
ctaButtonUrl | No | Per-post CTA button URL |
sidebarCtaTitle | No | Per-post sidebar CTA title (sticky card beside the post; a bar under the header on mobile) — overrides the project sidebar CTA when sidebarCtaTitle, sidebarCtaButtonLabel, and sidebarCtaButtonUrl are all set, even if the project's sidebar CTA is off |
sidebarCtaText | No | Per-post sidebar CTA paragraph |
sidebarCtaBullets | No | YAML list of bullet points (max 6); start one with an emoji to use it as the icon |
sidebarCtaButtonLabel | No | Per-post sidebar CTA button label |
sidebarCtaButtonUrl | No | Per-post sidebar CTA button URL |
Markdown body
Everything after the closing --- is the article body. Standard Markdown works: headings, lists, links, fenced code blocks with language tags, blockquotes, and images.
Inline images use standard Markdown with absolute HTTPS URLs. Upload via the dashboard editor, blogizi upload, POST /api/upload, or MCP upload_post_image. The CLI also auto-uploads relative local paths like  on draft / update / publish. Optional frontmatter: coverImageUrl (HTTPS) or coverImage (local path for the CLI).
Title is shown separately
Your blog page renders the title from frontmatter. Avoid opening the body with a heading that simply repeats the title — start with an introduction paragraph or a meaningful section heading instead.
Upload or publish from the CLI
Authenticate once and select your project (see CLI publishing), then push any local file:
blogizi draft path/to/my-post.md
blogizi update path/to/my-post.md
blogizi publish path/to/my-post.mddraft and publish create a post; update revises by slug. They recalculate word count and reading time. blogizi draft saves a draft; blogizi publish makes it live; blogizi update keeps visibility unless the file sets status.
Where to store files
Put files anywhere in your repo — blogizi draft, blogizi update, and blogizi publish take an explicit path. A blogizi-posts/ (or posts/) folder in the project root is a convenient convention.
Not in frontmatter
These fields live on the post record but aren't part of the YAML block — set them in the dashboard after publishing if you need them:
- Tags — filtering on your blog homepage and related posts
- CTA style — card / banner / minimal / split / accent is project-level (Settings → CTA); only the CTA copy fields above are per-post
Creating vs updating
blogizi draft and blogizi publish each create a new post. If a post with the same slug already exists, the API returns a conflict error. To revise an existing article, run blogizi update on the same file (or edit it in the dashboard).