Skip to content

5etools: Inline spell, feat, and condition references

Data comes from the 5etools-src submodule at repo root. Clone with submodules:

Terminal window
git submodule update --init --recursive

Spell is auto-imported in MDX. It resolves data in this order: optional spell prop (inline object), then json (file under the docs tree), then name (+ optional src) against the 5etools mirror.

From the 5etools mirror (name, optional src)

Section titled “From the 5etools mirror (name, optional src)”

src is the 5etools book key (case insensitive), e.g. phb, xphb, tce.

<Spell name="Burning Hands" src="phb" />
<Spell name="Burning Hands" />

Without src, the first matching entry is chosen with XPHB preferred over PHB when both exist (see build log for a one-time ambiguity warning).

Override the visible label by passing children:

<Spell name="Burning Hands" src="phb">fire cone</Spell>

Point json at a path relative to src/content/docs/ (no .. segments). The file must match the 5etools spell shape and is validated with SpellDataSchema (same as *.spell.json in collections).

<Spell json="world/misc/examples/fire-bolt.spell.json" />

If the root object is { "spell": [ … ] }, pass name to choose one entry (case-insensitive match):

<Spell json="path/to/bundle.spell.json" name="Fire Bolt" />

Pass a spell object directly (for example from a static JSON import). Takes precedence over json and name.

import fireBolt from './fire-bolt.spell.json';
<Spell spell={fireBolt} />

For full stat blocks and collection-backed frontmatter, see Spell and Magic Item JSON (5etools).

Same pattern as spells; data is read from data/feats.json.

<Feat name="Alert" src="phb" />

ConditionDisease reads data/conditionsdiseases.json. The file lists both conditions and diseases. Optional src pins the book when the same name exists in legacy and revised sources; if src is omitted, XPHB / XDMG are preferred over PHB / DMG, and a one-time build warning is logged when that ambiguity applies.

<ConditionDisease name="Blinded" />
<ConditionDisease name="Blinded" src="phb" />

In CommonMark, a blank line ends a paragraph. If you put an empty line before <Spell />, the spell becomes the start of a new paragraph after “…the spell”, which looks like the name is repeated and can sit oddly next to “, but…”. Keep the component on the same line as the surrounding sentence:

They act similarly to the spell <Spell name="Antimagic Field" />, but…

References render as static HTML: one span wrapper, a button trigger, and a tooltip panel toggled with CSS (group-hover / group-focus-within) so there is no astro-island or second hydration wrapper. If an entry is missing, the label still renders with a title fallback.

Tab to the trigger to show the tooltip; tab away to hide it. (There is no per-instance client script, so Escape does not blur the trigger; use Tab or click outside.)