Zaraz’s Middle Ground: JSONata for In-Flight Data Shaping

Zaraz is Cloudflare’s managed loader for third-party JavaScript tools—analytics, conversion pixels, and similar widgets—promising faster, safer delivery. When an event fires, Zaraz can attach a payload you define at configuration time, enriching something like a "Button Clicked" event with extra context: the element’s ID, the user_id cookie at that moment, or any number of custom fields.

That data typically arrives through zaraz.track("event name", { properties }) or zaraz.ecommerce() calls in your site code. But what if you need to shape that payload before it reaches the tool—normalizing values, running computations, or extracting just the fields you care about?

Until recently, the only remedy was Worker Variables, which send the data to a Cloudflare Worker for arbitrary JavaScript processing. That works, but it can be heavy machinery for small transformations. In response to user feedback, Zaraz now integrates JSONata directly, offering a lightweight middle path.

JSONata: A Query Language for JSON

JSONata describes itself as a JSON query and transformation language. It’s likely familiar in spirit to users of jq, the command-line JSON processor, but JSONata’s syntax is designed to be more approachable. Best of all, it ships as a JavaScript library, which made integration into Zaraz straightforward.

“JSONata” shines when you want to interrogate a JSON document. Given input like:

{
  "name": "Jane Smith",
  "address": {
    "street": "123 High St",
    "city": "London"
  },
  "pets": [
    { "type": "hamster", "name": "Rex" },
    { "type": "parrot", "name": "Milo" },
    { "type": "parrot", "name": "Alfie" }
  ]
}

You can run expressive queries over it:

$count(pets) // 3

address.city // London

pets[type="parrot"].name // ["Alfie", "Milo"]

There’s a rich catalog of documentation, and if you want to experiment, a live playground lets you test expressions before wiring them into your setup.

Expressions Where You Need Them

JSONata support is woven into the fields of every Action, Trigger, and Variable in Zaraz. Before you write an expression, you need to know what document you’re operating on. As with Worker Variables or the HTTP Request tool, JSONata has access to the full Zaraz Context—a structure holding data from your zaraz.track() and zaraz.ecommerce() calls, plus automatically captured details like page URL, cookies, page title, and user-agent string. The complete context reference is in Zaraz’s documentation.

Using JSONata in a field is simple: wrap your expression in double curly braces. The text inside will be evaluated against the current Zaraz Context, and the resulting value is what gets used.

For a practical example, consider wanting a lowercase comparison. Say the string comes from a cookie named loggedIn that holds a boolean string. In a Trigger match rule, you could enter {{ $lowercase(system.cookies.loggedIn) }} as the value. Now, whatever the case of the cookie’s contents, the Trigger will see it in lowercase before evaluating the rule.

BLOG-1939 Embedded Image - ufoPOk

JSONata can also handle simple math. Suppose you track a cart with:

zaraz.track("Cart Viewed",
  {  products:
	[
	{
  	sku: '2671033',
  	name: 'V-neck T-shirt',
  	price: 14.99,
  	quantity: 3
	},{
  	sku: '2671034',
  	name: 'T-shirt',
  	price: 10.99,
  	quantity: 2
	},
	],
  }
);

Now, to get the grand total in any Action field, use {{ $sum(client.products.(price * quantity)) }}. That expression multiplies each product’s price by its quantity, then sums the entire collection.

BLOG-1939 Embedded Image - kqwvNw

Availability

JSONata support is available to all Zaraz users at no extra cost, and it’s enabled automatically for every website. No separate configuration step is required. The feature is intended for sending finely tuned data to your providers or APIs with minimal code and no extra data infrastructure to maintain—just an expression in a field where it’s needed.