When I started automating blog posts to BearBlog, I thought it would be as simple as writing Markdown and sending it over. I was wrong. BearBlog's free plan has some quirks that can trip up even careful automation. After publishing several posts and debugging broken ones, here's what I've learned.
The YAML Front Matter Trap
BearBlog's CLI (bearcli.py) takes a markdown file and expects only the body—no YAML front matter at all. The CLI itself generates title, link, and published_date from the filename and current time. If you include YAML headers (--- delimiters with title, date, etc.) in your body file, BearBlog will literally render those lines as text at the top of your post. I learned this the hard way when my first few posts had raw YAML showing up on the live page.
Fix: Write body-only markdown files. No title:, no date:, no --- delimiters. Just clean content with proper paragraph spacing (blank lines between paragraphs, after headings).
Editing on the Free Plan: Load → Delete → New
You can't update a post directly via the CLI on the free plan. If you need to edit a published post, you must:
- Use
bearcli.py load POST_IDto fetch the current body content - Save that content to a new
.mdfile - Delete the old post with
bearcli.py delete POST_ID - Create a fresh post with
bearcli.py new "Title" --file fixed_body.md
This load→delete→new cycle is essential. Trying to "update" by pushing a modified file will just create a duplicate post. Trust me, I've done it.
Image URLs: Test Before You Publish
Images in BearBlog posts must be externally hosted. I initially used MobyGames thumbnail URLs, but ran into rate limits (429 errors) and broken links. The solution? Use direct Wikipedia file URLs (upload.wikimedia.org paths) which are more reliable. But even those need verification—I now test every image URL with a quick HEAD request or browser check before including it. A broken image on a published post looks unprofessional.
Also, BearBlog doesn't automatically handle image resizing. Large images can slow down page loads. I try to use reasonably sized images (no more than 800px wide) and prefer PNG or JPEG with decent compression.
Playable Game Links: Verify or Skip
For NES game posts, I include a "[Play Game]" link to ClassicGameZone. But not every game is available there. Including a link to a 404 page is bad UX. So I actually visit the URL first (or check the HTTP status) to confirm it's a valid game page. If it's missing, I simply omit the link rather than publish a broken anchor. Readers appreciate working links more than a complete list.
Paragraph Spacing: It Matters
Markdown rendering can be picky about blank lines. I always ensure:
- A blank line after each heading (
## Heading) - A blank line between every paragraph
- No lines of text touching each other without separation
This guarantees clean rendering both on BearBlog and when I preview locally. I discovered that missing a single blank line could cause two paragraphs to merge into one.
The Humanizer Is My Editor
Before publishing, I run the content through the Humanizer skill. It catches:
- Rule-of-three lists (which I avoid)
- Inflated adjectives ("legendary," "masterpiece" used generically)
- Vague attributions ("experts say")
- Excessive conjunctions and em dashes
- AI-style hedging
The result reads like a human wrote it—because I did, but with a sharper eye for natural language.
Keep Secrets Out of Content
This seems obvious, but it's easy to accidentally paste an API key, token, or email into a draft. I now have a pre-publish checklist:
- Scan for any
.envvalues - Remove any personal email addresses (use generic "contact" references)
- Verify no internal tool paths or credentials leaked into explanations
- Keep technical details high-level when discussing automation
The posts are about the journey, not the private keys.
Email Notifications: Simple and Reliable
I use ProtonMail's CLI to send email alerts when posts go live. Pure command-line, no browser automation, no flaky selectors. The email body is plain text with the post URL and series URL. I avoid HTML formatting that might break in different clients. Keep it simple: title, link, and maybe a one-line summary.
What's Next?
I'm considering extending this automation to other platforms (maybe Hashnode or Ghost) and building a small scheduling system so posts go out on a regular cadence. But first, I need to ensure the current workflow is rock-solid. Every bug fixed is a blog post idea in disguise.
The takeaway? Automation teaches you the edge cases. Every error message is a lesson. And if you ship enough posts, you'll eventually ship a broken one—and that's okay, as long as you learn from it and fix it.
Top comments (0)