Documentation/Tutorials/Write in Markdown
Documentation

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

FieldRequiredNotes
titleYesPage title and H1 on your blog
descriptionYesMeta description for SEO and social cards (~150–160 chars)
keywordYesPrimary SEO keyword for the post
slugYesURL path — lowercase letters, numbers, and hyphens only (e.g. my-post-title)
statusNodraft or published — blogizi draft always sets draft; blogizi publish always sets published regardless
dateNoYYYY-MM-DD — informational / CLI display; does not rewrite publishedAt on already-published posts
scheduledAtNoFuture 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
readingTimeNoLeave as 0 — recalculated from content on publish
wordCountNoLeave as 0 — recalculated from content on publish
ctaTitleNoPer-post CTA title — overrides the project branding CTA when ctaTitle, ctaButtonLabel, and ctaButtonUrl are all set
ctaSubtitleNoPer-post CTA subtitle (optional even when CTA is shown)
ctaButtonLabelNoPer-post CTA button label
ctaButtonUrlNoPer-post CTA button URL
sidebarCtaTitleNoPer-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
sidebarCtaTextNoPer-post sidebar CTA paragraph
sidebarCtaBulletsNoYAML list of bullet points (max 6); start one with an emoji to use it as the icon
sidebarCtaButtonLabelNoPer-post sidebar CTA button label
sidebarCtaButtonUrlNoPer-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.

![Architecture diagram](https://media.blogizi.com/content/your-post-id/1234567890.png)

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 ![Alt](./images/diagram.png) 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.md

draft 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).