Solving Broken Images When Exporting Craft Documents

The Problem

When exporting articles from Craft to Ulysses and Micro.blog, images referenced by temporary URLs quickly become broken links. Craft hosts images with public URLs that expire within days, leaving your published posts with missing images. This automation workflow solves that problem by re-hosting all images on Micro.blog before publishing.

How It Works

The workflow is triggered when you request to publish a Craft document to Micro.blog. Here's what happens behind the scenes:

  1. A request is send in Claude with the article title to publish
  2. The n8n automation searches my Craft space and uses a scoring algorithm to find the exact document (preventing false matches from body text mentions)
  3. The document's content is converted from Craft's block format into clean HTML, preserving headings, lists, formatting, quotes, code blocks, and more
  4. The workflow scans for all image URLs pointing to Craft's backend hosting
  5. Each image is downloaded from Craft and immediately re-uploaded to Micro.blog's permanent media storage
  6. All image references in the post are updated to point to the new, stable Micro.blog URLs
  7. The article is published as a draft to Micro.blog for review before going live, which is a manual process

Key Technical Features

Smart Document Matching

The search algorithm scores results by how closely the document title matches the request. Exact matches score 100, partial matches score lower, and body-text mentions are heavily penalized. This ensures I get the right document even if multiple articles discuss similar topics. The search is done via Craft API endpoint.

Rich Content Support

The conversion preserves all the formatting: paragraph styles, heading levels (h1–h4), bullet and numbered lists, blockquotes, task checkboxes, strikethrough text, code blocks, horizontal rules, and rich link bookmarks. Consecutive list items are automatically grouped into single lists.

Graceful Image Handling

If an image fails to upload (for example, unsupported formats like AVIF), the system keeps the original Craft URL in your post rather than failing entirely. This ensures the article publishes even if one image has issues.

Manual Review

All posts are created as drafts in Micro.blog. I can review the final result, check that images loaded correctly, and make edits before publishing it live.

Workflow Specifications

  • Trigger: Webhook at craft-to-microblog (available in my n8n instance wirh MCP endpoint enabled)
  • Input: Simple JSON with the article title to publish
  • APIs used: Craft's document search and block retrieval, Micro.blog's Micropub standard API
  • Typical execution: 4–6 seconds (image uploads add ~1.5 seconds)
  • Output: Draft post URL, preview link, and edit URL from Micro.blog

Why This Matters

This automation fills a gap in the content publishing process. I can craft and organize my articles in Craft, a versatile and attractive writing environment, and then publish them to Micro.blog without losing images or manually fixing broken links. I use a similar method to publish new editions of the Ephemeral Scrapbook newsletter, which relies on a separate n8n workflow to handle Ghost CMS-specific requirements.

Now that I manage all my issues and enhancements in GitHub Issues, I just realized that I could automate many manual workflows on issues closure… many interesting ideas here, like updating the README.md file once an issue is closed by Claude Code. 🤓

I’m not planning to go any further with my Lovable experimentation. The reason? On the free plan, custom domains are not supported. It’s a complete deal-breaker. Plus, the free tier doesn’t provide enough credits to build something meaningful, and you have to wait 24 hours before getting more. Too bad, it was somewhat promising. Pass. 😔 The good thing is that I’m focusing on Vercel for hosting web apps like mine.

From now on, I will document and track all bugs in my custom web apps using GitHub, instead of relying on checklists in Craft. Centralizing everything isn’t ideal; organizing issues in their appropriate locations is smarter. Additionally, Claude Code will be able to close issues on my request.

Today I went ahead and fully migrated “Who Is Numeric Citizen” website to Realmac Software Elements Hosting instead of Chillidog Hosting service. Here’s why: A) Chillidog was recently sold, and people are already complaining about a decline in service quality. B) What Realmac Software accomplished with Elements in the last year is nothing less than exemplary. They built mature, native web design software for the Mac and a hosting service. I prefer to reward this company for this hard work.

The migration was really simple and took me less than an hour. The service is a bit more expensive but includes more storage and unlimited network bandwidth. This could enable a future option for hosting more photography-related content. Finally, the web service feels snappier, too!

Coming Soon

One of the first things I’m going to do when I come back home is to deploy my new blog visual theme built entirely with Claude Code. It’s ready. I’m anxiously awaiting for the moment I put that project behind. Next, I’ll spend some time on Who Is Numeric Citizen website design and hosting solution (I’m thinking of leaving Chillidog Hosting hosting service to go with Elements’ built in solution instead).

I realized I forgot to clearly state the design goals before starting to build this custom theme for Micro.blog. They became clearer as I progressed and explored how Hugo and Micro.blog work, especially with assistance from Claude AI, and as I encountered various challenges. Here are the goals: a) I want a theme that stands out and doesn’t resemble typical Micro.blog blogs. b) I aim to minimize the use of external plugins, ensuring that all functionality is integrated within the custom theme. c) I want the same theme to be usable on more than one blog (I have two). Stay tuned for more news.

Takeaways From Building a Custom Micro.blog Theme Using Claude Code and Claude AI

Building a custom visual theme for Micro.blog presents unique challenges at the intersection of web design, static site generation, and AI-assisted development. This blog post captures practical insights and lessons learned from creating a custom theme with Claude Code and Claude AI, including key considerations on Hugo compatibility, plugin conflicts, and theme architecture.

  • Claude AI isn’t well-trained on Micro.blog architecture and dependency on Hugo static website generator. Claude doesn’t make a clear distinction between Hugo’s capabilities and Micro.blog’s unique features.
  • Plugins are a challenge because they might inject conflicting formatting instructions into your custom-built theme. It’s hard to debug.
  • Plugins can conflict with each other.
  • Don’t use the latest Hugo version (0.158) and stay on 0.117 if you use many plugins. By removing low-value plugins, you increase your chance of using version 0.158.
  • The workflow for updating a GitHub repo hosting your custom theme to the deployment on The process of Micro.blog is tedious because it’s manual and slow, especially for large websites and Hugo rendering engine. Hugo 0.158 could help, unless it conflicts with one plugin that you need.
  • More than ever: less is more. Keep it simple, and problems will be kept at bay: removing low-value plugins can make a big difference.
  • Test the website after each plugin removal, force a rebuild of the entire site to cleanup things. It’s slow but it might help debug later.
  • If a plugin introduces support for smart code in blog posts, after removing that plugin, Hugo will generate errors. These blog posts need to be either updated or deleted.
  • If the custom-built theme covers a specific design area, like a /photos page, don’t use a plugin touching the same area, prioritize the custom-built theme and skip the plugin. The idea is to have a self-contained custom theme.
  • Stay away from abandoned-ware plugins.
  • Prefer adding stuff in the custom theme instead of relying on an external plugin, so the theme is self-contained.
  • The lower the number of plugins, the better the chance you can use the latest version of Hugo.
  • Using the custom.css functionality, which helps externalize and override the custom-theme’s styling, speeds up testing different styling options.

Creating a custom Micro.blog theme using Claude AI revealed both the power and limitations of AI-assisted development in specialized ecosystems. While the tools provided invaluable support, the real breakthroughs came from hands-on debugging and understanding the unique interactions between Hugo, Micro.blog, and plugins. These takeaways form the foundation for a more robust theme architecture—one that will continue to improve with future iterations.

I’m still not done with my design. As I progress, you can visit my test blog.