Utilido blog
Markdown structure to verify before you publish
Headings, lists, fences, and spacing that break when copying between apps, plus a preview checklist before CMS or repo publish.
- markdown
- writing
- documentation
- cms
- preview
By Benchehida Abdelatif · Published May 10, 2026 · Updated May 27, 2026 · 7 min read
Markdown looks simple until a missing blank line turns a heading into a paragraph, or a list item swallows the next section. The failure mode is quiet: the preview in your editor looks fine, but GitHub, the CMS, or the ticket renderer shows one long block of text. Before you paste into a readme, changelog, or support article, run structure checks in the markdown previewer on Utilido. The broader developer tools hub also holds JSON and encoding helpers when your doc embeds API examples.
This article is a publish-time checklist for structure, not for prose style. It pairs with word-count limits on descriptions when you need length guardrails after the skeleton is sound.
Why structure breaks across apps
Each renderer implements CommonMark-ish rules with small differences: blank lines around lists, whether inline HTML is allowed, how tables align, and whether a single # line inside a list item is a heading or literal text. Copying from Notion, Google Docs, or email often injects invisible characters or hard line breaks that break fences.
Treat the destination renderer as the source of truth. Preview there, or in a tool that matches your destination closely, not only in the editor theme you like.
Heading hierarchy and document outline
Use one h1 per page when the platform expects it; many sites inject the title separately, so body copy may start at h2. Do not skip levels without reason (## then ####) because auto-generated tables of contents and accessibility tools assume a sane outline.
Leave a blank line before and after headings. Some parsers require it; others forgive absence until you paste into a stricter CMS.
## Setup
Install dependencies first.
### Windows notes
Use WSL when paths contain spaces.
If your platform auto-numbers headings, avoid manual numbers in the heading text (## 1. Intro) unless the CMS disables its own numbering.
Lists, nesting, and paragraph breaks
Unordered lists need consistent markers (- or * , pick one per doc). Ordered lists need sequential numbers; most renderers renumber for you, but pasted Word exports sometimes produce 1. on every line.
Nested items need indentation (often two or four spaces, or a tab, depending on the parser). A paragraph inside a list item needs a blank line after the list marker line before the paragraph text continues.
Checklist syntax (- [ ] / - [x]) works on GitHub but not everywhere. For generic CMS targets, use bullets and plain text status words instead of checkbox tokens.
Fenced code blocks
Open and close fences on their own lines with the same backtick count. Specify a language after the opening fence when you want syntax highlighting:
```json
{ "ok": true }
```
Do not indent triple-backtick fences with spaces unless you intend an indented code block inside a list, which confuses many authors. If a fence fails to close, everything until the end of the file may render as monospace.
For shell examples, use bash or sh consistently so copy buttons and highlighters behave. Escape inner triple backticks by using a longer outer fence (four backticks) when you must show Markdown examples inside Markdown.
Links, images, and reference style
Inline links: [label](/path). Reference-style links help long docs but hide destinations in a second pass; grep-friendly repos often prefer inline for internal paths.
On this site, Utilido blog posts are text-only: do not embed markdown image figures in frontend/blog/src/content/blog/*.md. Elsewhere (GitHub readmes, wikis, newsletters), use the usual image syntax with meaningful alt text, not “image1”.
Verify relative vs absolute URLs. A readme on GitHub may use ./assets/step.png while a CMS may want a full path from the site root.
Tables, blockquotes, and horizontal rules
Tables use pipe columns with a header separator row:
| Field | Meaning |
|-------|---------|
| exp | Expiry |
Keep tables narrow. Wide tables break mobile readers; sometimes a list is clearer.
Blockquotes use > at the start of each line. For multi-paragraph quotes, repeat > on blank-line-separated paragraphs.
Horizontal rules (--- on its own line) can clash with YAML frontmatter delimiters in some tools. In mixed Markdown/YAML files, know whether your generator strips frontmatter before render.
HTML, comments, and inline snippets
Some platforms allow raw <details> or <kbd> tags; others strip HTML for security. If you rely on HTML, confirm the destination allowlist.
HTML comments <!-- like this --> may appear in repo source but surprise reviewers when exported to PDF. Remove scaffolding comments before publish.
CMS and ticket paste hazards
- Smart quotes from Word (
"") break JSON examples inside fences. - Trailing spaces can change line breaks in some renderers (two spaces + newline).
- Tab-indented lines may not register as code or lists.
- Pasted URLs sometimes include zero-width characters; retype the scheme if links 404 mysteriously.
After paste, scroll the full preview on mobile width. Broken lists often show up only when the viewport is narrow.
Preview workflow with the markdown previewer
- Paste or type draft Markdown into the markdown previewer.
- Walk headings in the side outline or skim
##lines for skipped levels. - Click every link and open every fence to see if one swallowed the rest of the doc.
- Copy the cleaned source back to your CMS or git repo.
When the doc includes API payloads, validate JSON in the JSON formatter after you fix fences. For data-shape debugging after backend changes, see JSON debug checklist after API changes.
Combine with length limits after structure passes
Marketing descriptions, meta tags, and essay limits care about characters, not headings. After structure looks correct, use the word counter for limits on blurbs. Twitter, LinkedIn, and CMS SEO fields count differently (with or without spaces); note which limit your field enforces.
Do not fix length by deleting blank lines that lists depend on. Shorten sentences instead.
Publishing checklists for repos vs blogs
Readme or internal wiki
- Relative links resolve on the default branch.
- Code fences match the project’s real language versions.
- Images live in-repo or on a stable CDN, not on a personal drive link.
Blog or changelog
- Title and description live in frontmatter or CMS fields, not duplicated as a stray
h1unless intended. - FAQ sections use
###questions under one## FAQheading when your static generator expects that shape.
For CSV or JSON appendices attached to the same doc set, CSV and JSON round trip without breaking data covers tabular exports that often get pasted under Markdown tables.
The blank line I still forget before lists
I have shipped changelogs where a list ate the next heading because I removed “extra” blank lines while trimming word count. The preview in my IDE wrapped things kindly; GitHub rendered one bullet and a wall of text. Now I run the markdown previewer after every paste from email or Slack, even for a two-line note. If the preview shows a merged list, I add the blank line back before I argue about punctuation. That habit costs less than one confused reader thread per month, and I treat a failed preview the same way I treat a failing unit test: fix structure before wordsmithing.
FAQ
Why does my heading show as plain text?
Usually a missing blank line above the # line, or spaces before # that block setext/ATX parsing. Remove leading spaces and add a blank line before the heading.
Can I mix - and * bullets in one list?
Many parsers accept both, but inconsistent markers make diffs noisy. Pick one style per document.
Do I need closing fences for indented code blocks?
Fenced blocks need an explicit closing fence. Indented blocks (four spaces) end at the first non-indented line; they are easy to break accidentally inside lists.
Will GitHub-flavored Markdown match my CMS?
Not always. Tables, task lists, and autolinks differ. Preview on the target platform or use the strictest renderer in your chain.
Should I fix structure or grammar first?
Fix structure first so you do not edit sentences that will move when lists and headings parse correctly. Grammar passes on stable blocks save rework.
About the author
Benchehida Abdelatif , Software engineer. Benchehida Abdelatif builds Utilido: fast browser utilities for images, PDFs, and developer workflows, with client-side processing where it matters for privacy. More about Utilido.