lecture.studio

How to hide or skip a slide in Marp (without a blank page)

Marp has no directive that hides a slide. A CSS display: none class hides the content but leaves a blank page in the PDF and an empty slide in the PPTX; an appendix after the end with <!-- _paginate: skip --> keeps drafts out of the numbering but in the file. To remove slides for real, a small marp-cli engine drops every slide marked <!-- _hide: true -->. All three checked with marp-cli 4.5.

This guide shows what each approach produces, then the engine recipe, then the plain answer for decks that must render in tools without an engine option.

What "hidden" means in each export

Approach HTML PDF PPTX
section.hidden { display: none } via a class blank slide in the sequence blank page empty slide
Appendix after the end, _paginate: skip visible, unnumbered present present
Engine that drops _hide: true slides removed removed removed
Delete or move to another file removed removed removed

The blank page is the surprise: Marp draws each slide inside an SVG page, and hiding the section inside it does not remove the page.

The engine recipe

Save this next to the deck:

// hide-engine.mjs: drop every slide marked <!-- _hide: true -->, before page numbers are counted.
export default ({ marp }) => {
  marp.customDirectives.local.hide = (v) => ({ hide: v });
  return marp.use((md) => {
    md.core.ruler.before("marpit_directives_apply", "drop_hidden_slides", (state) => {
      const out = [];
      let skip = false;
      for (const t of state.tokens) {
        if (t.type === "marpit_slide_open" && t.meta?.marpitDirectives?.hide) skip = true;
        if (!skip) out.push(t);
        if (t.type === "marpit_slide_close" && skip) skip = false;
      }
      state.tokens = out;
    });
  });
};

Mark slides:

---

<!-- _hide: true -->

# A draft I am not ready to show

---

Export:

marp --engine ./hide-engine.mjs deck.md --pdf

The marked slides are gone from the output, and because the rule runs before Marpit applies directives, page numbers stay consecutive. Without --engine, the same deck renders every slide, so the marks are harmless in tools that do not know them.

To switch between a full deck and a student version, keep two commands: one with the engine (student PDF) and one without (your own notes), or mark the answer slides and export both.

When you cannot use an engine

The VS Code extension, Lecture Studio and the online editor render the deck as written. There the honest options are:

  1. An appendix. Move the slides after the closing slide, mark them <!-- _paginate: skip -->, and stop presenting at the closing slide. Students who get the PDF see the appendix, so keep answers out of it.
  2. A second file. week5-slides.md for the room and week5-answers.md for you; the answers file can ![bg] or copy the question slides it needs.
  3. Comment the slide out? Do not: an HTML comment that is not a directive becomes a speaker note on the previous slide, and the text is still in the file.

Skipping in the room

Presenting from HTML or from Lecture Studio, you can jump past a slide by pressing → twice. That is skipping, not hiding, and it is fine for a slide you decide to drop on the day; plan the deck so that nothing depends on the skipped slide.

FAQ

How do I hide a slide in Marp?

There is no directive. Remove it with a marp-cli engine that drops slides marked _hide: true, move it to an appendix with _paginate: skip, or keep it in a separate file. A CSS display: none leaves a blank page in the PDF.

Why does my hidden Marp slide show as a blank page in the PDF?

Each slide is an SVG page; hiding the section inside it does not remove the page. Use the engine or delete the slide.

Can I skip a slide in the Marp page numbering?

Yes: <!-- _paginate: skip --> hides the number on that slide and leaves it out of the count.

Does the hide directive work in VS Code?

_hide is a custom directive that only the engine understands. VS Code renders every slide; use an appendix or a second file there.