# Write in Markdown

> YAML frontmatter format for hand-written posts uploaded or published via the CLI.

HTML version: https://blogizi.com/docs/markdown-frontmatter
Markdown version: https://blogizi.com/docs/markdown-frontmatter.md

You don't need `blogizi draft` or an AI agent to use the CLI. Write a `.md` file locally with YAML frontmatter, then upload it as a draft with `blogizi upload` or publish live with `blogizi publish`.

## When to use this

- You already write in your editor (VS Code, Obsidian, etc.)
- You version posts in git alongside your repo
- You want full control over wording without running an AI draft

## Frontmatter template

Every post file starts with YAML frontmatter between `---` delimiters. The CLI parses these fields and sends them to Blogizi when you publish.

```markdown
---
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 |
| `status` | No | `draft` or `published` — `blogizi upload` always sets `draft`; `blogizi publish` always sets `published` |
| `date` | No | `YYYY-MM-DD` — defaults to today if omitted |
| `readingTime` | No | Leave as `0` — recalculated from content on publish |
| `wordCount` | No | Leave as `0` — recalculated from content on publish |

## 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.

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

Inline images use standard Markdown syntax. Upload images in the dashboard post editor (rich text or Markdown mode) to get hosted URLs on `media.blogizi.com`, or paste any public HTTPS URL. Cover images (hero + listing cards) are set separately in the dashboard — not in frontmatter.

> **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 (see [CLI publishing](/docs/cli-publishing)), then push any local file:

```sh
blogizi upload path/to/my-post.md
blogizi publish path/to/my-post.md
```

Both commands read the file and recalculate word count and reading time. `blogizi upload` saves the post as a draft in your dashboard; `blogizi publish` makes it live on your blog.

## Where to store files

Put files anywhere in your repo — `blogizi upload` and `blogizi publish` take an explicit path. If you use `blogizi draft`, the CLI saves to a `blogizi-posts/` folder in your project root by default; you can follow the same convention for hand-written posts.

## 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
- **Cover image** — hero image on the article and listing cards (without one, the auto-generated OG image is used on cards)

> **Warning:** `blogizi upload` 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, edit it in the dashboard post editor.
