Coming in Broadcast 3.0. Until then, this page applies only to the Upcoming (edge) build.

Liquid Filters Hook

Use this hook to change how a value looks in an email. A merge tag makes a value. A filter changes a value that is already there.

How it works

You write a filter in an email:

Your balance: {{ subscriber.data.balance | local_money_format: "EUR" }}

The filter name is your plugin ID and the filter name, joined with _. . and - become _. So the filter format in local.money is local_money_format.

Broadcast collects all the different inputs in a batch and calls your function once. If 100 people have the same balance, you get that input once.

Full example: money

manifest.json:

{
  "id": "local.money",
  "name": "Money",
  "version": "1.0.0",
  "requires": { "broadcast": ">=3.0.0 <4.0.0", "pluginApi": "1" },
  "hooks": {
    "liquidFilters": ["format"]
  }
}

dist/main.js:

export default definePlugin({
  liquidFilters: {
    async format({ items }) {
      return items.map(({ input, args }) => {
        const amount = Number(input);
        const currency = args[0] ?? "USD";
        if (Number.isNaN(amount)) return input;

        return new Intl.NumberFormat("en", { style: "currency", currency }).format(amount);
      });
    },
  },
});

With the input 19.5 and the argument "EUR", the result is €19.50.

What you get and return

You get this:

{
  "name": "format",
  "items": [
    { "input": "19.5", "args": ["EUR"] },
    { "input": "abc", "args": [] }
  ]
}

You return an array with one output for each item, in the same order:

["€19.50", "abc"]

Common mistakes

You return the wrong number of items. Each output is matched by its place. If you drop an item, the outputs after it land on the wrong input. Always use items.map.

You treat the input as a number. Inputs and arguments are strings. Use Number(input), and return the input as it was if it is not a number.

You use the filter in a test send. Plugin hooks do not run in transactional emails or test sends.

You expect a failure to stop the email. Filters have 5 seconds and fail open: the value is empty and the email goes out. HTML output works as for merge tags.

Last updated

Was this page helpful?

Thanks for your feedback!

Thanks for letting us know. We'll work on improving this page.