Multiline tags for all tags, JSON literal arguments for tags and filters, Liquid error stack traces, safer WebSocket subscriptions, upgraded file upload library
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. -
Upgraded internal file upload library: The underlying library that handles file uploads and processing (powering user uploads and image versions) has been upgraded to its latest version. This brings upstream security patches, bug fixes, and performance improvements. No changes are required in your application - uploads continue to work exactly as before.