Markdown Not Rendering? Fix Line Breaks, Tables and Lists
Most broken Markdown comes down to a few rules: line breaks, the table delimiter row, list indentation, underscores in words, unclosed code fences and HTML blocks. Here is each one with its fix.
When Markdown is not rendering the way you expect, the cause is almost always a syntax rule, not a bug in the renderer. Paste the text into the Markdown editor and fix it while you watch the live preview.
The rules below come from the CommonMark and GitHub Flavored Markdown (GFM) specifications, which GitHub follows. Every example was checked with marked 18, a GFM parser.
Markdown line break not working
A single newline inside a paragraph counts as a space. Two lines typed one under the other render as one line. This is the most common surprise, and it is what the specification says.
- End the line with a backslash
\to force a break. - End the line with two spaces. This works, but many editors strip trailing spaces on save, and the break silently disappears.
- Leave an empty line to start a new paragraph instead.
- Write
<br>where the site allows HTML.
Why does the same text work in a GitHub comment but not in a README? GitHub renders issue, pull request and discussion comments with every newline as a break. Markdown files follow the specification. Parsers expose the same switch:
import { marked } from "marked";
marked.parse("one\ntwo"); // "<p>one\ntwo</p>" - one line on screen
marked.parse("one\ntwo", { breaks: true }); // "<p>one<br>two</p>"Markdown table not rendering
A GFM table needs a delimiter row directly under the header, with the same number of cells as the header. Without it, the whole block stays plain text.
| Name | Role |
| :--- | ----: |
| Ana | Admin |- No
| --- |row under the header: plain text. - Two header cells but one delimiter cell: plain text.
- A
|inside a cell splits it, even inside backticks. Write\|instead. - Colons set alignment:
:---left,:---:centre,---:right.
A missing blank line before the table is rarely the cause. A table directly under a paragraph line still renders in GFM.
Nested list indentation in Markdown
A sub-item belongs to its parent only when it is indented to where the parent's text starts. After - that is two spaces. After 1. it is three, and after 10. it is four.
1. Install
- two spaces: a separate list after the numbered one
1. Install
- three spaces: nested under "Install"Four spaces nests correctly under both - and 1. items, which is why many style guides use it everywhere.
Underscores and asterisks inside words
In GFM an underscore inside a word is literal, so my_var_name stays as written. An asterisk inside a word still starts emphasis: un*frigging*believable comes out with the middle in italics. Put identifiers in backticks, or escape the character with a backslash.
A code block that swallows the rest of the page
An opening fence of three backticks with no closing fence runs to the end of the document, so every heading below it shows as code. Close every fence. To show a fence inside a code block, make the outer fence longer, or use ~~~:
````markdown
```js
console.log("inner fence");
```
````Text indented by four spaces after a blank line also becomes a code block. If a paragraph suddenly shows in a monospace box, check its indentation.
Markdown inside HTML tags is ignored
Inside an HTML block such as <div> or <details>, Markdown is not processed until a blank line ends the block. Put an empty line after the opening tag and another before the closing tag, and **bold** inside becomes bold.
Some tags never appear at all. GitHub removes scripts, styles, iframes and forms from rendered Markdown, so HTML that works in a local file can vanish from a README. The Markdown editor uses a similar allow-list, so you see the problem before you publish.
Mermaid diagram not rendering in Markdown
GitHub and GitLab draw a code block fenced with mermaid as a diagram. Plain CommonMark renderers show the same block as code, so first check that the place you publish supports Mermaid. When it does and the diagram still fails, the cause is usually one of these:
- The first line must name the diagram type, such as
graph TD,flowchart LRorsequenceDiagram. Without it Mermaid reports that no diagram type was detected. - Brackets and parentheses inside a label break the parser:
A[Status (200)]fails. Quote the label:A["Status (200)"]. - A node named
endin lower case ends the flowchart early. WriteEndorEND.
Headings that show the # sign
#Title without a space stays as plain text. Write # Title. The same applies to every level up to ######.
Related tools
Write, preview and export PlantUML diagrams in your browser - rendered 100% locally.
Draw flowcharts and diagrams with 18 drag-and-drop shapes, export PNG or SVG, or share a private link. Nothing is uploaded.
Generate placeholder lorem ipsum text by paragraphs, sentences, or words.
Encode text or files to Base64, with an optional URL-safe variant.
Percent-encode text for safe use in URLs and query strings.
Related guides
Both turn plain text into diagrams, and both are free. They differ in which diagrams they draw well, where they render without extra setup, and where your diagram source goes. Here is how to choose.
A flowchart is easy to start and easy to get wrong. Learn the standard symbols, plan the steps first, connect shapes properly and export a clean image.
Lorem ipsum has short, even words, so it hides the layout bugs real content exposes. Here is a set of test strings worth keeping next to it, and the CSS that keeps them from breaking a layout.
Base64 turns bytes into plain text so they can travel where only text is allowed. Here are the five places developers meet it most, with real examples, and the cases where it is the wrong tool.
The same character can be fine in one part of a URL and break another. Here is a reference table of what each JavaScript and Python function does with the characters that matter.