Homepage

Unreleased

Unreleased - only on Staging

NEW

  • Multiline tag syntax: Liquid tags can now span multiple lines, so long or deeply nested arguments can be formatted for readability instead of being crammed onto a single line. This works for tags across the board (assign, function, include, background, etc.), for example:

{% function result = 'lib/create_order',
   customer_id: customer.id,
   items: [
     { "sku": "ABC", "qty": 2 },
     { "sku": "XYZ", "qty": 1 }
   ],
   note: "priority" %}

  • JSON literal arguments: JSON object and array literals - including nested structures, variables as values, and string interpolation - can now be passed directly as arguments to tags and filters, without first building them up with assign or parse_json, for example:

{% include 'shared/card', data: { "title": "Hello", "tags": ["news", "featured"], "active": true } %}

{% function total = 'lib/sum', numbers: [1, 2, 3] %}

{% assign items = value | default: [] %}

IMPROVED

  • Better error handling with stack traces: Errors raised while rendering Liquid now include a stack trace pointing at the file and line where the error occurred, instead of only a top-level message. The trace is captured through the same mechanism as the log tag, making it much easier to locate the source of a problem in your logs.

  • More reliable and secure WebSocket subscriptions: Subscribing to a WebSocket channel now always resolves to an explicit verdict. Previously, an error raised while evaluating a subscription could bubble up and leave the client with no confirmation frame at all, causing it to resubscribe indefinitely. Now every rejected subscribe attempt receives a structured subscription_error message (delivered right before the reject_subscription frame) carrying:

    • a stable, machine-readable code (unauthorized, instance_not_found, subscribed_partial_error, or internal) that your client can switch on,
    • a human-readable message, and
    • a retryable boolean telling the client whether resubscribing later may help.

    Because the reject_subscription frame cannot carry a payload, the client should read this message in its received(data) handler and correlate it by subscription identifier - the rejected() callback receives no arguments. Messages sent to the client are always generic (no internal detail is leaked over the socket); a Liquid error raised inside your channel's subscribed partial is instead written to the error log under the WebSocketSubscribeError code, so you can debug it from the admin.

  • New websockets_require_subscribed_partial feature flag: This new app/config.yml flag makes WebSocket channel authorization fail-closed - a channel with no channels/<name>/subscribed partial rejects every subscription instead of falling back to the legacy open default that admits any same-origin subscriber. It defaults to true (secure by default); set websockets_require_subscribed_partial: false in your config.yml to keep the legacy open behaviour. Regardless of this flag, a cross-origin connection without an authorizing subscribed partial is always rejected.

FIXED

Questions?

We are always happy to help with any questions you may have.

contact us