---
title: 'Content helpers'
description: 'How drafts, wikilinks, heading IDs, element attributes, and image handling work in Baseline, and the rules that keep content predictable.'
slug: 'content-helpers'
type: 'article'
date: 2026-05-02T00:00:00.000Z
lang: 'en'
url: 'https://www.eleventy-baseline.dev/docs/core-reference/content-helpers/'
---

This section covers the small but important pieces that keep content predictable as it scales.

Together, these helpers define how content moves through the system without adding friction or hidden behavior.

---

## Drafts

Any page with `draft: true` in front matter is dropped on `build` and kept on `serve`. The preprocessor is on automatically; you don't register it. Use it for in-progress pages you want to preview locally without shipping.

```yaml
---
title: 'Half-written thoughts'
draft: true
---
```

---

## Wikilinks

Forward links, MediaWiki-style. All resolved at render time, all combinable:

- `[[slug]]` links to the page with that slug. The link text defaults to the page's title.
- `[[slug#anchor]]` links to a heading on that page. The anchor is slugified for you.
- `[[slug:lang]]` hops to the translation in the named language. Use the short code that keys `settings.languages`, e.g. `[[about:fr]]`, not a full BCP 47 tag.
- `[[slug|alias]]` sets custom link text. The pipe is the alias separator.

The forms compose. `[[about:fr#team|notre equipe]]` is valid. Misses (unknown slug, missing translation) render as the original literal text rather than a broken link, so a typo is visible without crashing the build.

Slugs are global within the default language. Wikilinks themselves are forward-only; the content-graph pre-pass does build a reverse index, exposed as `data._backlinks` per page and `_navigator.backlinks` site-wide, so authors can opt in to "what links here" surfaces without the wikilink syntax sprouting them automatically.

Curated cross-references still win over automatic ones in narrative prose.

---

### Where they work

Wikilinks are a markdown-it inline rule, so they resolve in `.md` body content only. They do not run in Nunjucks templates or in front matter values. If you need a link from a layout or a data field, write the URL directly.

---

### Formatters will eat them

{% alertBlock "warning" %}

Wikilinks are not standard markdown, so a formatter has no reason to preserve them. Prettier rewraps and reflows markdown, and an alias can be lost in the process: `[[commercial-support | commercial support]]` comes back as `[[commercial-support]]`.

Nothing warns you. A wikilink that lost its alias still resolves, so the build stays green and the link text silently changes to the page title. One that gets broken outright renders as literal text, which is the design, but on a page you were not looking at.

If you run format-on-save, exclude markdown. In `.prettierignore`:

```
# Wikilinks are not standard markdown and Prettier rewrites them
**/*.md
```

{% endalertBlock %}

---

## Heading IDs

Every heading in your Markdown gets a stable `id` attribute automatically. The id is the slugified heading text, so `## Implementation details` becomes `<h2 id="implementation-details">`. You can link to it directly with `#implementation-details`, and `_node.headings` carries the same id so a generated table of contents matches the anchors it points at.

Repeated headings dedup with WordPress-style numeric suffixes: the first stays `foo`, the second becomes `foo-2`, the third `foo-3`, and so on. Stable across builds for the same source order.

---

### Overriding an id

A manual id wins over the auto one. Use the attribute syntax described below:

{% raw %}

```markdown
## Implementation details {#impl}
```

{% endraw %}

Renders as `<h2 id="impl">`. Manual ids are also seeded into the dedup map, so a later heading with the same slugified text gets the next free name (`implementation-details` here, since `impl` does not collide).

---

### Why one source

Heading ids live in two places that need to agree: the rendered HTML you anchor links to, and the `headings[].id` field on the [[content-graph | content graph]] that templates read for a TOC. They are assigned once in the markdown engine; the rendered HTML and the graph read the same id back. No drift between "the link" and "the table of contents entry".

---

## Element attributes

The {% raw %}`{#id .class key="value"}`{% endraw %} syntax attaches attributes to any block element. It runs through the upstream `markdown-it-attrs` plugin, which Baseline ships as a direct dependency.

{% raw %}

```markdown
## A section heading {#impl .lead}

A paragraph with a class. {.note}

![Alt text](/img/hero.jpg){#hero loading="eager"}
```

{% endraw %}

The attributes attach to the element that ended just before them. Useful for adding a class to a paragraph, anchoring a heading with a specific id, or marking an image so a transform can find it later.

Loaded under `safeUse`, so if you already wired `markdown-it-attrs` yourself with different options, your registration wins and Baseline's is skipped silently.

The same dedup applies to the heading-id and wikilinks plugins; you can layer your own markdown extensions without fighting Baseline's wiring.

---

## Images

The shortcode is Baseline's. The heavier transform isn't.

{% stepsBlock "compact" %}

- {% raw %}`{% image %}`{% endraw %} is always registered. `eleventy-img` is a peer dependency, so it sits in your `package.json` rather than inside the plugin; install it alongside Baseline.
- AVIF and WebP by default. No JPEG fallback. Modern browsers handle these and the file size difference is real.
- The HTML transform that rewrites `<img>` into responsive `<picture>` (`eleventyImageTransformPlugin`) is opt-in. You add it yourself if you want it. When it is present, the shortcode marks its own output with `eleventy:ignore` to avoid double-processing.

{% endstepsBlock %}

Alt text matters. The shortcode warns when it is missing (use an empty string for decorative images). The [[image-transform | image transform]] how-to walks you through the responsive pipeline.

---

## See also

- [[image-shortcode | Image shortcode]] - every argument, in full.
- [[content-graph | Content graph]] - what wikilinks resolve against, and where headings end up.
- [[sitemaps-and-drafts | Sitemaps and drafts]] - the rest of the draft story.
- [[content-organisation | Content organisation]] - where these helpers sit in a real content tree.
