Tag Reference

This page covers every non-effect span tag in ETA markup. Each section shows accepted attributes, defaults (drawn from MarkupParser.java), and a usage example. Effect tags (rainbow, wave, shake, etc.) are handled by the effects pipeline and documented in the Effects catalog.

Entry shape: tag name, one-line summary, syntax block, parameter table, example, and notes where behavior isn’t obvious.


bold (b), italic (i), underline (u), strikethrough (s), and obfuscated (obf) apply the corresponding vanilla ChatFormatting style to their content. None of them take attributes.

TagAliasEffect
boldbBold weight
italiciItalic slant
underlineuUnderline decoration
strikethroughsStrikethrough decoration
obfuscatedobfVanilla obfuscation (random character cycling)

Example

<b>Bold</b>, <i>italic</i>, <u>underline</u>, <s>struck</s>, <obf>????</obf>

Notes

obfuscated is vanilla MC’s random-character cycling (equivalent to ChatFormatting.OBFUSCATED). It’s distinct from the obfuscate effect tag, which is an ETA animation with speed and mode controls. See the Effects catalog for obfuscate.

Source: MarkupParser.java


Sets a static text color. When value contains a comma or the col attribute is present, the parser treats the tag as a gradient and forwards it to GradientEffect instead.

Syntax

<color value=RRGGBB>text</color>
<c #FF8800>text</c>

Parameters

NameAliasTypeDefaultDescription
valuepositional first tokenhex stringnone (required)Color in hex (FF8800, #FF8800, or named). When this value contains a comma the tag is forwarded to GradientEffect.
colorhex stringnoneExplicit named attribute; checked before value when resolving a static color.
colanyWhen present, the tag is always forwarded to GradientEffect regardless of value. Used to supply additional gradient stops.

Example

<color value=FF8800>Orange text</color>
<c #FF8800>Also orange</c>

Notes

The resolution order for static color is: color attribute first, then value. Gradient forwarding check happens before either: if value contains , or col is present, the tag acts as a gradient and the color attribute is not consulted for static color. See the Effects catalog for gradient usage.

Source: MarkupParser.java


Sets the rendering font for the enclosed text. When bold is active on the same span and the selected font has a registered _bold variant, the parser automatically switches to that variant.

Syntax

<font id=norse>text</font>
<font name=cinzel>text</font>

Parameters

NameAliasTypeDefaultDescription
idvalue, font, namestringFont alias or full namespace:path resource location.

The four attribute names are checked in order: id, value, font, name. The first non-null value wins.

Built-in aliases

AliasResource locationBold variant
norseemberstextapi:norseemberstextapi:norse_bold
norse_boldemberstextapi:norse_bold
metamorphous, metaemberstextapi:metamorphousnone registered
cinzelemberstextapi:cinzelemberstextapi:cinzel_bold
cinzel_boldemberstextapi:cinzel_bold
almendraemberstextapi:almendraemberstextapi:almendra_bold
almendra_boldemberstextapi:almendra_bold
cardoemberstextapi:cardoemberstextapi:cardo_bold
cardo_boldemberstextapi:cardo_bold

Any full resource location string (mymod:myfont) is accepted directly; no alias registration required.

Example

<font id=norse>Runic inscription</font>
<bold><font id=cinzel>Chapter Title</font></bold>

In the second example, bold is active when the span is created, so the parser replaces emberstextapi:cinzel with emberstextapi:cinzel_bold automatically.

Notes

The auto-bold switch happens in createSpanWithCurrentStyles, not in applyTagToSpan. It runs at span creation time, not at tag-push time, so the font slot on the style stack still holds the base font. Only the resolved TextSpan that carries content gets the bold variant.

metamorphous has no bold variant registered in FontAliasRegistry (it’s added to NO_BOLD_VARIANT), so the switch is skipped for it.

Source: MarkupParser.java


Resolves a Minecraft translation key to the viewer’s locale. The substitution runs before span parsing, so the resolved text slot into the span structure but ETA tags written inside a .lang file are not re-parsed.

Syntax

<lang:item.minecraft.diamond>
<lang key=item.minecraft.diamond>
<lang key='commands.give.success.single' args='1,Diamond,Steve'>

Parameters

NameAliasTypeDefaultDescription
keypositional first token in attribute formstring""Translation key to resolve.
argscomma-separated stringnonePositional substitution arguments for %s placeholders. Quote the whole value if any token contains whitespace.

Example

You picked up <lang:item.minecraft.diamond>.
<lang key='commands.give.success.single' args='1,Diamond,Steve'>

Notes

Two forms are accepted by the LANG_TAG regex:

  • Shorthand <lang:KEY>: the part after : is the key directly, no attributes parsed.
  • Attribute form <lang key=... args=...>: standard attribute parsing. key can also be supplied as value (positional first token).

Resolution uses Language.getInstance().getOrDefault(key) for zero-arg lookups, and Component.translatable(key, args).getString() when args is supplied. Missing keys render as the key string itself, matching Component.translatable’s default. If the resolver throws, the key string is returned.

Translation values are treated as plain text by ETA. Any ETA markup that happens to appear inside a .lang file is not re-parsed.

Source: MarkupParser.java


Attaches a click event to the enclosed text.

Syntax

<click action=open_url value=https://example.com>Visit</click>
<click link=https://example.com>Visit</click>

Parameters

NameAliasTypeDefaultDescription
actionstringClick action type. See accepted values below.
valuestringTarget URL, command string, page number, or clipboard text.
linkstringShorthand for action=open_url value=<link>. Ignored when action is also present.

Accepted action values

ValueCanonical formBehavior
open_urlopen_urlOpens a URL in the system browser.
run_commandrun_commandRuns a command as the clicking player.
suggest_commandsuggest_commandPlaces a command in the chat input box.
copy_to_clipboard, copycopy_to_clipboardCopies value to the clipboard.
change_pagechange_pageChanges the page in a book.

Example

<click link=https://tysontheember.dev>Visit the site</click>
<click action=run_command value=/home>Go home</click>

Notes

If both link and action are present, action takes precedence and a warning is logged. An unrecognized action value logs a warning and the click event is not applied. A missing value also logs a warning and the event is skipped.

Source: MarkupParser.java


Attaches a hover tooltip to the enclosed text.

Syntax

<hover text="Tooltip text">Hover over me</hover>
<hover action=show_text value="Tooltip text">Hover over me</hover>

Parameters

NameAliasTypeDefaultDescription
actionstringHover action type. Only show_text is currently supported.
valuestringThe tooltip text to display.
textstringShorthand for action=show_text value=<text>. Ignored when action is also present.

Example

<hover text="Forged in the nether">Netherbane</hover>

Notes

In v3.0.0-beta.1, only show_text is a supported action. Any other action value logs a warning and the hover event is not applied. A missing value also logs a warning and the event is skipped.

Source: MarkupParser.java


Renders an inline item icon. Accepts both wrapping and self-closing forms.

Syntax

<item value=minecraft:diamond/>
<item id=minecraft:diamond size=2 x=0 y=-2/>
<item value=minecraft:sword>Sword</item>

Parameters

NameAliasTypeDefaultDescription
valuepositional first tokenresource location stringnone (required)Item registry ID.
idresource location stringnoneExplicit named attribute for item ID. Checked after value.
sizecountinteger1Stack size displayed on the icon.
offsetxxfloat0Horizontal render offset in pixels.
offsetyyfloat0Vertical render offset in pixels.
nbtSNBT stringnoneNBT data for the item.

Example

Reward: <item value=minecraft:diamond size=3/>

Notes

The resolution order for the item ID is value attribute first (or the positional first token), then id. When both are present, value wins.

In wrapping form (<item ...>text</item>), the closing tag triggers the inline render at that position; the text content of the tag is not rendered as item label. The item icon is emitted as a separate TextSpan with empty content.

If size can’t be parsed as an integer, the parser logs at DEBUG and falls back to 1. Offset parse failures similarly fall back to 0.

Source: MarkupParser.java

Renders an inline entity portrait. Accepts both wrapping and self-closing forms.

Syntax

<entity value=minecraft:zombie/>
<entity id=minecraft:creeper scale=1.5 yaw=30 spin=1/>

Parameters

NameAliasTypeDefaultDescription
valuepositional first tokenresource location stringnone (required)Entity type registry ID.
idresource location stringnoneExplicit named attribute for entity ID.
scalefloat1.0Render scale.
offsetxxfloat0Horizontal render offset in pixels.
offsetyyfloat0Vertical render offset in pixels.
yawfloat45Yaw rotation in degrees.
pitchfloat0Pitch rotation in degrees.
rollfloat0Roll rotation in degrees.
lightinglightinteger15Lighting level for the entity render (0-15).
spinrotatefloatnoneContinuous spin speed. Omit to disable.
animationanimstring"idle"Animation state to play.
nbtSNBT stringnoneNBT data for the entity.

Example

Watch out for <entity value=minecraft:creeper scale=1.2 yaw=20/>!

Notes

Rotation defaults apply only when any rotation attribute is set. If none of yaw, pitch, or roll appear on the tag, span.entityRotation is called with the code defaults (yaw=45, pitch=0, roll=0).

spin/rotate is only applied when the attribute is present. When absent, no spin is set on the span (there is no always-applied default).

Source: MarkupParser.java


Embeds a display duration in the markup string. This is extracted by a separate method (extractDuration) before any span parsing occurs.

Syntax

<dur:N>

Where N is a positive number (integer or decimal float, e.g. 60, 2.5).

Example

<dur:100> <rainbow>Quest complete!</rainbow>

Notes

<dur:N> is not a span tag and is not processed by TAG_PATTERN. It’s matched by its own regex <dur:(\d+(?:\.\d+)?)>. Only the first match is consumed; subsequent <dur:...> occurrences in the same string are left as literal text.

When no <dur:N> is found, extractDuration returns -1 for the duration value, signaling to the caller that no override was specified.

Callers that use parse directly instead of extractDuration will not strip this tag, and <dur:...> will appear as unmatched text (the TAG_PATTERN colon would need to be in the first character position to even try to match, but dur matches the tag name and :N> would be the attribute string; in practice the colon-form <dur:N> is handled by the dedicated regex, not the span parser).

Source: MarkupParser.java


Any datapack-registered preset name is usable as a tag directly. When the parser encounters an unknown tag name it falls through to PresetRegistry.get(tagName). If a matching preset is found, its style overrides and effects are applied to the span.

<my_preset>Styled text</my_preset>

See Presets for the preset schema and the bundled preset list.


Inside Patchouli book entries, if a book defines a macro for an unprefixed name (for example "<b>": "$(l)"), the macro takes precedence and ETA never sees that tag. Writing <eta-bold> instead sidesteps the collision: Patchouli is unlikely to have a macro named eta-bold, so the ETA tag survives the Patchouli pipeline intact.

Because eta- names contain a hyphen they pass through ETA’s span parser unchanged. The mechanism that makes them useful in Patchouli is that Patchouli does not consume them (no matching macro), so the text containing <eta-bold> reaches ETA where, critically, ETA also cannot parse it, since the hyphen breaks the regex match.

In practice this convention is only useful when Patchouli’s own macro processing has been configured to map the raw tag string back to a form ETA can handle, or when the Patchouli pipeline leaves the full string intact for ETA to post-process at a later stage. Outside Patchouli contexts, use unprefixed tag names.

Source reference: README.md: Patchouli Compatibility