Skip to main content
Tags are special components that perform operations on a section of your template. TemplateDX provides a set of built-in tags that you can use to manipulate and transform data within your templates. Or, you can create your own custom tags.

Creating Custom Tags

You can create custom tags by extending the TagPlugin class and registering them with the TagPluginRegistry.

Extending TagPlugin

Create a class that extends TagPlugin and implements the transform method:
import { Node } from 'mdast';
import { TagPlugin, PluginContext } from '@anthropic-ai/templatedx';

interface MyTagProps {
  prefix?: string;
}

class MyTagPlugin extends TagPlugin<MyTagProps> {
  async transform(
    props: MyTagProps,
    children: Node[],
    context: PluginContext
  ): Promise<Node[] | Node> {
    const { nodeHelpers } = context;

    // Convert children to markdown text
    const content = nodeHelpers.toMarkdown({
      type: 'root',
      children: children,
    });

    // Apply transformation
    const prefix = props.prefix ?? '> ';
    const prefixedContent = content
      .split('\n')
      .map(line => prefix + line)
      .join('\n');

    return [{
      type: 'text',
      value: prefixedContent,
    } as Node];
  }
}

The transform Method

The transform method receives three arguments:
  • props - The attributes passed to the tag
  • children - An array of AST nodes representing the tag’s children
  • context - A PluginContext object containing:
    • nodeHelpers - Utilities for working with AST nodes (toMarkdown, isMdxJsxElement, etc.)
    • scope - The current variable scope
    • createNodeTransformer - Factory to create a transformer for processing child nodes
    • tagName - The name of the tag being processed
The method must return a Promise resolving to either a single Node or an array of Node objects.

Registering Custom Tags

Register your custom tag with the TagPluginRegistry:
import { TagPluginRegistry } from '@anthropic-ai/templatedx';

// Register the plugin with one or more tag names
TagPluginRegistry.register(new MyTagPlugin(), ['MyTag', 'Prefix']);
After registration, you can use the tag in your templates:
<MyTag prefix="// ">
  This is some content
  that will be prefixed
</MyTag>

Example: Quote Tag

Here’s a complete example of a custom tag that wraps content in a blockquote:
import { Node, Root } from 'mdast';
import { TagPlugin, PluginContext, TagPluginRegistry } from '@anthropic-ai/templatedx';

interface QuoteProps {
  author?: string;
}

class QuotePlugin extends TagPlugin<QuoteProps> {
  async transform(
    props: QuoteProps,
    children: Node[],
    context: PluginContext
  ): Promise<Node[]> {
    const { nodeHelpers } = context;

    const content = nodeHelpers.toMarkdown({
      type: 'root',
      children: children,
    } as Root);

    let result = content
      .split('\n')
      .map(line => '> ' + line)
      .join('\n');

    if (props.author) {
      result += `\n> \n> -- ${props.author}`;
    }

    return [{
      type: 'text',
      value: result,
    } as Node];
  }
}

// Register the tag
TagPluginRegistry.register(new QuotePlugin(), ['Quote']);
Usage:
<Quote author="Albert Einstein">
  Imagination is more important than knowledge.
</Quote>
Output:
> Imagination is more important than knowledge.
>
> -- Albert Einstein

Built-In Tags

ForEach

The ForEach tag allows you to loop through an array. Syntax
<ForEach arr={props.arr}>
  {(item, index) => ...}
</ForEach>
Parameters
  • arr: Array<T> An array of items you want to iterate on
  • children: (item: T, index: number) => Node - A callback function for each item
Example
<ForEach arr={[1, 2]}>
  {(item, index) => (
    <>
      * item: {item}, index: {index}
    </>
  )}
</ForEach>
Output:
* item: 1, index: 0
* item: 2, index: 1

Conditionals

The If, ElseIf and Else tags allows you to conditionally output content. Syntax
<If condition={props.boolA}>
  ...
</If>
<ElseIf condition={props.boolB}>
  ...
</ElseIf>
<Else>
 ...
</Else>
Parameters If/ElseIf:
  • condition: boolean - The condition to check
  • children: Node - The node to render if condition is true
Else:
  • children: Node - The content to render if no previous condition was met.
Example
<If condition={1 + 1 == 3}>
  1 + 1 is not 3
</If>
<ElseIf condition={1 + 1 == 2}>
  1 + 1 is 2
</ElseIf>
<Else>
  Fallback
</Else>
Output:
1 + 1 is 2

Raw

The Raw tag allows you to output raw text without interpolation. Syntax
<Raw>
  ...
</Raw>
Parameters
  • children: Node - The raw text
Example
<Raw>
  {props.name}
</Raw>
Output:
\{props.name}