Skip to content
Log in

Respond - Liquid Tag Reference

On this page

The respond simple tag sends a custom HTTP response and stops rendering immediately. Use it in a Liquid controller to return JSON from API endpoints, send error responses, or override the default page rendering.

:::note This tag works only inside a Liquid controller template (at controllers/<controller>/<action>.liquid). It is typically used in the before or after blocks. Once called, normal page rendering is skipped. :::

When respond runs

Use respond to short-circuit rendering and send a custom response:

```liquid

{% before %} {% assign product_id = current_request.params.id %}

{% if product_id == blank %} {% respond body: ‘{“error”: “product_id required”}’, status: 400, layout: false %} {% endif %}

{% params product_id: product_id %} {% endbefore %} ```

When respond is called, rendering stops immediately and the response is sent to the client.

Syntax

```liquid

{% respond body: response_body, status: 200, layout: false %} ```

Property Value
Tag Name respond
Type Simple tag
Source StoreConnect

Parameters

Parameter Type Required Description
body String Yes The response body. Pre-serialize objects with the \| json filter.
status Integer No HTTP status code. Defaults to 302, so set it explicitly whenever you are returning a body. Common values: 200, 400, 401, 403, 404, 422, 500
layout Boolean No Whether to wrap the response in the page layout (default: true). Set false for JSON and other non-HTML bodies
notice String No A flash notice message (available on the redirected page)
alert String No A flash alert message (available on the redirected page)
data Hash No Additional data to pass to the response (typically for JSON APIs)
to String No Redirect path after responding (use with notice/alert)

What’s available in respond

  • current_request.params — still accessible
  • All globals — current_store, current_customer, current_cart, etc.
  • Liquid filters — use | json to serialize objects before responding
  • Liquid objects — render them to JSON or string format

Common tasks with respond

1. Return a JSON error response

```liquid

{% before %} {% assign product_id = current_request.params.id %}

{% if product_id == blank %} {% respond body: ‘{“error”: “product_id is required”}’, status: 400, layout: false %} {% endif %}

{% params product_id: product_id %} {% endbefore %} ```

2. Return cart data as JSON

```liquid

{% before %} {%- new Map result -%} {%- assign result = result | set_key: “cart_count”, current_cart.items.size -%} {%- assign result = result | set_key: “cart_total”, current_cart.total -%} {%- assign result = result | set_key: “status”, “success” -%} {% respond body: result | json, status: 200, layout: false %} {% endbefore %} ```

3. Return HTML error page with status code

```liquid

{% before %} {% assign requested_id = current_request.params.id %}

{% params requested_id: requested_id %}

{% if requested_id == blank %} {% respond body: “<h1>Not Found</h1><p>The requested item does not exist.</p>”, status: 404 %} {% endif %} {% endbefore %} ```

Key behaviors

  • Stops rendering immediately — respond terminates the page template rendering
  • Replaces page output — the body you provide is sent as the full response
  • layout: false is typical for JSON — set layout: false when returning JSON to avoid wrapping it in the page template
  • Pre-serialize with | json — objects must be converted to JSON before sending as a response body
  • Flash messages supported — include notice or alert if you want to show a message on the target page
  • respond runs after response sent — in the final phase, respond is a no-op (the client already has their response)

Best practices

Always validate before responding

```liquid

{% before %} {% assign email = current_request.params.email %}

{% if email == blank %} {% respond body: ‘{“error”: “email is required”}’, status: 400, layout: false %} {% endif %}

{% action “account.send_welcome_email”, email: email %}

{% params email: email %} {% endbefore %} ```

Serialize objects to JSON explicitly

```liquid

{% before %} {%- new Map error_response -%} {%- assign error_response = error_response | set_key: “success”, false -%} {%- assign error_response = error_response | set_key: “message”, “Invalid quantity” -%} {%- assign error_response = error_response | set_key: “code”, “INVALID_QTY” -%}

{% respond body: error_response | json, status: 400, layout: false %} {% endbefore %} ```

Return success with data

```liquid

{% after %} {%- new Map success_response -%} {%- assign success_response = success_response | set_key: “status”, “success” -%} {%- assign success_response = success_response | set_key: “order_id”, current_cart.order_id -%} {%- assign success_response = success_response | set_key: “total”, current_cart.total -%}

{% respond body: success_response | json, status: 200, layout: false %} {% endafter %} ```

  • {% before %} — use respond here to reject requests early
  • {% after %} — use respond here to send custom data after rendering
  • {% final %} — respond does not work in final (response already sent)
  • See Liquid controller lifecycle for the complete flow

Difference from redirect

  • {% respond %} — sends a custom response body and HTTP status; rendering stops
  • {% redirect %} — sends a 302 (or custom status) redirect to a different URL
  • Use case — respond for custom content/JSON; redirect to send the user to a new page

Was this article helpful?

Was this article helpful?