Engineering Playbook • Web • Product
Building a Production-Grade Blog Engine: HTML Content, Media, SEO & Performance
This post is a realistic, production-style HTML payload you can store in content. It includes a structured layout, responsive media, accessibility details, internal anchors, embedded video, and SEO-friendly semantics—while staying safe for server-side rendering.

Why store HTML in content?
If your editor outputs HTML (or you run Markdown → HTML on publish), storing HTML can be the simplest path: the rendering layer becomes predictable, portable, and easy to cache. The key is to keep your HTML: semantic, accessible, and sanitized.
Want a subtle brand touch? You can safely reference SVG logos as images. For example, here's a Flutter logo SVG asset: Flutter_logo.svg.
A content model that scales
A scalable blog post isn't just paragraphs. It's a structured document: headings, figures, tables, notes, code, citations, and navigation anchors.
- Headings: enforce a consistent hierarchy (
h2thenh3) - Figures: always include
alttext and a caption - Code: store code blocks in
<pre><code>with a language hint - Links: use
rel="noopener noreferrer"for external targets
"A blog is a product. If you don't design the reading experience, the reader does it for you."
Images, video, and link strategy
1) Images that are stable
For demos, use durable public assets (e.g. Wikimedia-hosted files) so your staging environments don't break. Here's an example featured image:

2) Videos (responsive embeds)
Embed videos using a responsive container so they look good on mobile. Here's a YouTube playlist embed (Flutter Widget of the Week): playlist link.
3) Links that build trust
Link out to authoritative sources (docs, official packages, standards). Examples:
- Flutter brand usage guidance: flutter.dev/brand
- SVG rendering in Flutter: flutter_svg
SEO: meta, headings, and structured snippets
Your API already supports metaTitle and metaDescription. That's a great baseline. Inside the content, keep headings descriptive and avoid skipping levels.
Recommended SEO extras (optional)
- Add canonical URLs at render-time
- Generate OpenGraph/Twitter meta from
headlineImage - Include JSON-LD (Article schema) at render-time (not stored in content)
| Signal | Where | Why it matters |
|---|---|---|
| Meta title | DTO field | Search snippet + share title |
| Meta description | DTO field | CTR + preview text |
| Headings | HTML | Scan-ability + topical clarity |
| Alt text | HTML | Accessibility + image context |
Security: sanitization, iframes, and XSS
Storing HTML means you must treat it as untrusted input. Even if your editor is internal, assume compromise. Sanitization should happen on write (server), and optionally again on read (defense in depth).
Performance checklist
- Lazy-load images and iframes
- Use
decoding="async"for images - Precompute reading time server-side
- Cache rendered HTML (and purge on update)
- Serve images via CDN (or stable hosts)
// Example: reading time (rough)
const wordsPerMinute = 220
const words = plainText.split(/\s+/).filter(Boolean).length
const readingTime = Math.max(1, Math.ceil(words / wordsPerMinute))A "world-class" HTML section example
Below is an example pattern you can replicate in other posts: a mini-case-study with a diagram, a code snippet, and a small "try it" checklist.
Case study: turning content into a product feature
Imagine your blog powers onboarding, docs, and release notes. Suddenly, the content pipeline needs versioning, previews, moderation, and analytics.
-- Example: simple search index table for blogs
-- (Don't store HTML in the index; index extracted plain text.)
CREATE TABLE blog_search (
blog_id UUID PRIMARY KEY,
title TEXT NOT NULL,
excerpt TEXT,
content_plain TEXT NOT NULL,
tags TEXT[],
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);Try it checklist
- Render the HTML server-side
- Sanitize on write
- Generate
slugfromtitle - Compute
readingTimefrom extracted text - Track
viewCounton page view (rate-limited)
Attribution note: The demo images used here are served from Wikimedia's upload CDN. Always confirm licenses and attribution requirements for production usage.
