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
assignorparse_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_errormessage (delivered right before thereject_subscriptionframe) carrying:- a stable, machine-readable
code(unauthorized,instance_not_found,subscribed_partial_error, orinternal) that your client can switch on, - a human-readable
message, and - a
retryableboolean telling the client whether resubscribing later may help.
Because the
reject_subscriptionframe cannot carry a payload, the client should read this message in itsreceived(data)handler and correlate it by subscriptionidentifier- therejected()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'ssubscribedpartial is instead written to the error log under theWebSocketSubscribeErrorcode, so you can debug it from the admin. - a stable, machine-readable
-
New
websockets_require_subscribed_partialfeature flag: This newapp/config.ymlflag makes WebSocket channel authorization fail-closed - a channel with nochannels/<name>/subscribedpartial rejects every subscription instead of falling back to the legacy open default that admits any same-origin subscriber. It defaults totrue(secure by default); setwebsockets_require_subscribed_partial: falsein yourconfig.ymlto keep the legacy open behaviour. Regardless of this flag, a cross-origin connection without an authorizingsubscribedpartial is always rejected.