Headings in Jupyter Notebook: Markdown Cell Guide

September 11, 2026 · 9 min read

Headings in Jupyter Notebook: Titles and Sections in Markdown Cells

Headings in Jupyter Notebook live in Markdown cells, not code cells. Press Esc, then M to switch the cell to Markdown, type ## Your Heading with a space after the hashes, and run the cell with Shift+Enter. This guide covers the shortcuts, heading anchors, the Table of Contents panel, and how nbconvert picks the notebook title.

Why Isn't My Heading Rendering in Jupyter?

The most common cause is cell type. A new cell is a Code cell, so # Results is a Python comment and runs as nothing. Switch the cell to Markdown and run it, and the same line becomes a heading. There is no separate Heading cell type any more. IPython 3.0 removed heading cells in favour of Markdown headings when it introduced notebook format 4 in 2015. That's why old tutorials mention a menu item you can't find.

The second cause is the missing space. Jupyter's Markdown cell documentation says a heading starts with one or more # followed by a space. #Results renders as literal text with the hash still visible. The third cause is forgetting to run the cell: a Markdown cell shows its raw source until you press Shift+Enter or Ctrl+Enter.

How Do You Add a Header in Jupyter Notebook?

Jupyter has two modes. Edit mode is when you're typing inside a cell. Command mode is when the cell is selected but the cursor isn't in it, and single-key shortcuts work there. The keyboard route to a heading takes three steps:

  1. Press Esc to enter command mode.
  2. Press M to change the selected cell to Markdown (Y turns it back into Code).
  3. Press a number from 1 to 6 to insert that many # marks at the start of the cell, then Enter to edit the text.

JupyterLab's default shortcuts, checked in the current notebook-extension settings, bind 1 through 6 to change-cell-to-heading-1 through -6, but only while the selected cell is already a Markdown cell. So the M keypress has to come first. Two more shortcuts are handy once you know they exist: Shift+A inserts a new heading cell above the current one, and Shift+B inserts one below.

The menu route works in both JupyterLab and Notebook 7: select the cell, open the cell type dropdown in the toolbar (it reads Code by default), and choose Markdown. Then type the heading and run the cell.

# Customer Churn Analysis

## 1. Load the data

### 1.1 Raw export from the CRM

Each of those renders at a different size, and the number prefixes are plain text you type yourself. If you want automatic numbering instead, the Table of Contents panel below does it for you.

Heading Levels, Bold, and Code Inside a Jupyter Header

Six levels are available, # through ######. Use one H1 per notebook as the title, H2 for each major section, and H3 for steps within a section. Skipping a level (H1 straight to H3) still renders, but the Table of Contents indents oddly and nbconvert's HTML output inherits the gap. The general rules for hierarchy are in our Markdown headings guide; this post sticks to what Jupyter does with them.

Inline formatting works inside a heading. A header in Jupyter Notebook can contain bold, italic, inline code, and LaTeX:

## Fit the **baseline** model with `sklearn`

### Loss function $L = \sum (y - \hat{y})^2$

The first renders with "baseline" heavier than the rest of the heading and sklearn in monospace. The second renders the formula through MathJax once the cell runs, although sidebar outlines and exporters may show the raw source rather than the typeset math.

For the "how to make a bold heading" question, note that a heading is already bold by default; wrapping the whole line in ** changes nothing visible. Wrap a single word instead, or use a lower level, as covered in Markdown bold and italic.

Try Jupyter Notebook Headings in the Editor

The editor below renders the same Markdown a Jupyter cell would, so you can check spacing, levels, and inline formatting before pasting into a notebook.

Customer Churn Analysis

A Markdown cell renders this as the notebook title.

1. Load the data

Press Esc, M, then 2 to make a level-2 heading like this one.

1.1 Raw export with pandas

Inline code and bold work inside a heading.

2. Results

Jump back up with an anchor link: Load the data.

58 words331 characters15 lines
Markdown

How Do Heading Anchors and Internal Links Work?

JupyterLab gives every rendered heading an ID so you can link to it from another cell. The rule, from the createHeaderId function in JupyterLab's rendermime package, is simple: take the heading text and replace each space with a hyphen. Nothing is lowercased and punctuation stays put. So ## Load the Data gets the ID Load-the-Data, and you link to it with:

[Back to loading](#Load-the-Data)

Case matters. #load-the-data won't scroll anywhere. Because the ID is derived from the text, editing a heading breaks every link pointing to it. When a heading is long or likely to change, add a manual anchor instead and link to that:

<a id="loading"></a>
## Load the Data (raw CSV export, September 2026)

Later: [see loading](#loading)

Jupyter allows HTML in Markdown cells but sanitizes it, so <a id> survives while scripts and event handlers are stripped. One limitation: the automatic IDs are JupyterLab's own scheme, and other viewers such as GitHub's notebook renderer may build IDs differently, so a link that works locally can miss elsewhere. If you're building a manual table of contents cell, test it where readers will open the notebook.

Jupyter Notebook Title: Filename, First Heading, or Metadata?

A notebook's title is three separate things, and they don't stay in sync on their own. The browser tab and the JupyterLab file browser show the filename, churn.ipynb. The first H1 in a Markdown cell is what readers see at the top of the document. And nbconvert's HTML template sets the page <title> from a title key in the notebook metadata if one exists, falling back to the filename without its extension. It never reads your first H1.

To set the exported title explicitly, open the Property Inspector in JupyterLab's right sidebar, expand Advanced Tools, and add "title": "Customer Churn Analysis" to the notebook metadata JSON. Then jupyter nbconvert --to html churn.ipynb produces a page whose tab reads Customer Churn Analysis rather than churn. We prefer to keep all three identical, because a notebook named Untitled3.ipynb with an H1 of "Final Report" is the kind of thing that leaks into a shared drive.

The Table of Contents panel in JupyterLab's left sidebar reads every heading from your Markdown cells and lists them as a clickable outline. Its toolbar can number sections automatically (with an option to skip numbering H1s), collapse a section's cells, and run all the code cells under a heading. If a heading should stay out of the outline, append <a class="jp-toc-ignore"></a> to it. Headings that appear in cell outputs are included by default; the includeOutput setting turns that off.

Common Jupyter Notebook Heading Mistakes

Typing the heading in a Code cell. The symptom is a cell that runs and prints nothing, or a SyntaxError if you wrote ## Results in a language that doesn't treat # as a comment. Esc, M, Shift+Enter fixes it.

Indenting the heading. Four spaces or a tab before the # turns the line into an indented code block, so it renders in monospace with the hashes visible. Headings must start at column one of the cell. The same applies to a heading pasted in from a code editor that auto-indents.

Relying on a numbered prefix and the TOC numbering at once. If you type ## 2. Results and also switch on automatic numbering in the Table of Contents panel, the sidebar reads "2. 2. Results". Pick one system. For anything you'll reorder, the panel's numbering wins because it updates itself. The broader syntax, including tables and LaTeX cells, is in the Jupyter Markdown cheat sheet.

Jupyter Notebook Headings FAQ

Once you know that headings in Jupyter Notebook are just Markdown in a Markdown cell, the rest follows: Esc, M, a number key, and Shift+Enter. Keep one H1 as the title and match it to the filename and the metadata title before you export. Use anchors or the Table of Contents panel to navigate long notebooks. Draft the heading structure in the editor first if you want to see the hierarchy before it goes into cells.