# How to Handle Custom HTML Tags in html-to-pdfmake: A Complete Guide

> Learn to handle custom HTML tags in html-to-pdfmake using the customTag callback. Transform unknown elements into PDFMake nodes with this complete guide.

- Repository: [Aymeric/html-to-pdfmake](https://github.com/aymkdn/html-to-pdfmake)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Use the `customTag` callback option to intercept unknown HTML elements and transform them into valid PDFMake nodes before they reach the parser's default handler.**

The `html-to-pdfmake` library converts standard HTML into PDFMake document definitions, but it cannot natively recognize every custom element or specialized tag you might use. When the parser encounters an unsupported tag, it triggers the `customTag` callback defined in your options object, allowing you to inject custom logic at the default handler in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) lines 588–590.

## How the customTag Callback Works

When `htmlToPdfMake` processes an HTML element that does not match any built-in case in the `parseElement` switch statement, execution falls through to the `default` branch. According to the source code at [[`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) lines 588–590](https://github.com/aymkdn/html-to-pdfmake/blob/master/index.js#L588-L590), the library checks for `options.customTag` and invokes it using `.call(this)`, binding the internal parser instance to your function.

### Callback Parameters

The `customTag` function receives three parameters:

| Parameter | Type | Description |
|-----------|------|-------------|
| `element` | DOM Node | The native HTML element being processed |
| `ret` | Object | The current PDFMake fragment (may be empty) |
| `parents` | Array | Ancestor nodes for style inheritance |

Your callback may modify `ret` to add text, styles, or custom PDFMake keys, and must return the updated object. Because the function is called with `call(this)`, you have access to internal helper methods such as `applyStyle` and `parseStyle`.

## Practical Implementation Examples

### Basic Custom Tag Handler

The following example demonstrates handling a simple `<custom-tag>` element by replacing it with a paragraph containing static text:

```javascript
const html = `<custom-tag></custom-tag>`;

const result = htmlToPdfmake(html, {
  customTag({ element, ret }) {
    if (element.nodeName === 'CUSTOM-TAG') {
      // Replace the unknown tag with a paragraph containing custom text
      ret = { text: 'This is content inserted by a custom tag.' };
    }
    return ret;
  }
});

console.log(result);
// → { text: 'This is content inserted by a custom tag.' }

```

### QR Code Generator Implementation

This advanced example from the official documentation shows how to transform a `<code typecode="QR">` element into a PDFMake QR code node:

```javascript
const html = `<code typecode="QR" style="foreground:black;background:yellow;fit:300px">
                texto in code
              </code>`;

const pdfDef = htmlToPdfmake(html, {
  customTag(params) {
    const { element, ret, parents } = params;

    // Only act on our special <code> element
    if (ret.nodeName === 'CODE') {
      // Apply inherited styles first
      ret = this.applyStyle({ ret, parents: parents.concat([element]) });

      // Extract the inner text that will become the QR payload
      ret.qr = ret.text[0].text; // ← QR content
      delete ret.text;           // QR node does not need regular text

      // Mark the node so PDFMake knows it is a QR
      ret.nodeName = 'QR';
      ret.style = (ret.style || []).concat('html-qr');
    }
    return ret;
  }
});

```

The resulting definition contains `{nodeName:'QR', qr:'texto in code', style:['html-qr']}`, which PDFMake renders as a QR code when using a compatible QR extension.

### Wrapping Third-Party Widgets

Handle proprietary widget tags by extracting attributes and converting them to styled PDFMake elements:

```javascript
const html = `<my-widget data-value="42"></my-widget>`;

const pdfDef = htmlToPdfmake(html, {
  customTag({ element, ret, parents }) {
    if (element.nodeName === 'MY-WIDGET') {
      // Use the data-value attribute to create a table cell with custom background
      ret = {
        background: '#f0f0f0',
        text: `Widget value: ${element.getAttribute('data-value')}`
      };
      // Re‑apply styles from ancestors (margin, alignment, etc.)
      ret = this.applyStyle({ ret, parents });
    }
    return ret;
  }
});

```

## Accessing Internal Parser Methods

Because `customTag` is invoked using `options.customTag.call(this, ...)`, the callback executes within the context of the parser instance. This binding gives you access to internal helper methods such as:

- **`this.applyStyle({ ret, parents })`** – Applies inherited CSS classes and inline styles to your custom node
- **`this.parseStyle(styleString)`** – Parses CSS style strings into PDFMake-compatible style objects
- **`this.computeStyle(style)`** – Computes final styles after processing

Leveraging these methods ensures your custom tags respect the same styling cascade as standard HTML elements.

## Key Source Files Reference

| File | Purpose |
|------|---------|
| [[`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js)](https://github.com/aymkdn/html-to-pdfmake/blob/master/index.js) | Core parser; `customTag` hook resides in the `default` branch of `parseElement` (lines 588–590) |
| [[`README.md`](https://github.com/aymkdn/html-to-pdfmake/blob/main/README.md)](https://github.com/aymkdn/html-to-pdfmake/blob/master/README.md) | Official documentation of the `customTag` option (lines 38–50) |
| [[`example.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/example.js)](https://github.com/aymkdn/html-to-pdfmake/blob/master/example.js) | Usage examples that can be extended with `customTag` callbacks |
| [[`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js)](https://github.com/aymkdn/html-to-pdfmake/blob/master/browser.js) | Browser bundle supporting identical `customTag` functionality |

## Summary

- The `customTag` callback in `html-to-pdfmake` intercepts unknown HTML elements during the parsing phase at [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) lines 588–590.
- It receives the DOM element, current PDFMake fragment (`ret`), and parent nodes for style inheritance.
- The callback runs with parser context (`this.applyStyle`, etc.), allowing reuse of internal styling logic.
- Return a modified PDFMake node to replace the default handling of custom tags.
- Works identically in Node.js (via `jsdom`) and browser (via `DOMParser`) environments.

## Frequently Asked Questions

### What happens if I don't define a customTag handler?

When the parser encounters an unrecognized tag without a `customTag` callback defined, it processes the element's children but returns an empty object for the tag itself. This means custom tags effectively disappear from the final PDF output unless you explicitly handle them.

### Can I override standard HTML tags using customTag?

Yes. While `customTag` primarily handles unknown tags reaching the `default` branch, you can intercept standard tags by inspecting the `ret.nodeName` or `element.nodeName` inside your callback. However, for modifying behavior of built-in tags, preprocessing the HTML or using the `styles` option is often cleaner.

### How do I access element attributes in my custom handler?

The `element` parameter passed to your callback is a native DOM node, so you can use standard DOM methods like `element.getAttribute('data-value')`, `element.hasAttribute('typecode')`, or `element.attributes` to inspect HTML attributes and drive conditional logic in your PDF generation.

### Is the customTag callback supported when using the browser bundle?

Yes. The `customTag` functionality works identically in both Node.js and browser environments because the core parsing logic in [`index.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/index.js) is environment-agnostic. Whether you load the library via `require()` in Node or include [`browser.js`](https://github.com/aymkdn/html-to-pdfmake/blob/main/browser.js) in a `<script>` tag, the `customTag` option is available in the options object passed to `htmlToPdfmake`.