Update - Liquid Tag Reference
On this page
The update tag modifies a custom data field on an existing Salesforce record from within a Liquid controller template. Use it to write back custom field values to products, orders, or other data from your storefront.
Before you start
- The tag works only inside a Liquid controller template
- The Custom Data Mapping for the field must be marked as editable (Read/Write access)
- Only custom data fields mapped via Custom Data Mapping can be updated — standard and managed-package fields are read-only
- The record you update must exist and must be a Drop object (cast records from queries with
| cast:)
Syntax
```liquid
{% update
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
<drop> |
Drop | Yes | The object to update. Must be a Drop instance, not a raw record from {% query %}. Use \| cast: '<DropName>' to convert a query result. Examples: current_product, current_order, current_customer. |
field: |
string | Yes | The custom field API name (case-insensitive). Use the field name as it appears in the Custom Data Mapping, for example view_count__c or favorite__c. |
value: |
any | Yes | The new value to set on the field. Can be a string, number, boolean, or variable. |
How it works
The update tag makes a single field write to a Salesforce record. It runs silently: if the update succeeds, nothing is output; if preconditions fail, the tag is a silent no-op and a warning is logged to the web console (surfaced by {% debug %}), not the browser console.
Preconditions
The update succeeds only when ALL of these conditions are met:
- Controller template context — the tag is inside a Liquid controller template (in
controllers/<controller>/<action>.liquid). Outside a controller, the tag is a silent no-op. - Drop type — the first argument is a Drop, not a raw record from
{% query %}. Use| cast: '<DropName>'to convert. Example:{% assign product = record | cast: 'Product' %} - Editable field — the custom field has a Custom Data Mapping that is marked editable (Read/Write). If the mapping is Read-only, the tag logs a warning to the web console but makes no change.
- Custom field only — the field must be a custom data field from a Custom Data Mapping. Standard Salesforce fields (like
Name,IsActive) and managed-package fields cannot be updated.
Examples
Update a product view counter
Track how many times a product is viewed by incrementing a custom field:
```liquid
{% before %} {% assign new_count = current_product.data.view_count__c | default: 0 | plus: 1 %} {% update current_product, field: “view_count__c”, value: new_count %} {% endbefore %} ```
Store customer preferences
Save a customer’s display preference from a form submission:
```liquid
{% before %} {% assign preference = current_request.params.display_mode %} {% if preference != blank %} {% update current_customer, field: “preferred_display_mode__c”, value: preference %} {% endif %} {% endbefore %} ```
Update order item custom data
Set a custom field on an order retrieved from a query:
```liquid
{% before %} {% query ‘Order’ as orders, s_c__store_id__c: current_store.sfid, sfid: current_request.params.order_id %}
{% if orders.size > 0 %} {% assign order = orders[0] | cast: ‘Order’ %} {% update order, field: “internal_notes__c”, value: “Processed from storefront” %} {% endif %} {% endbefore %} ```
Important notes
:::warning
Only updates existing records. The update tag modifies fields on records that already exist in Salesforce. To create new records, use a Flow or Apex action instead.
:::
:::note
Scoping is your responsibility. Always filter by Store and, for customer-owned data, by the authenticated customer. For example, when updating a product, ensure it belongs to the current store. When updating customer data, ensure it belongs to current_customer. A query without these filters can match unrelated records.
:::
:::tip
Use the before phase for updates. Place {% update %} in a {% before %} block to ensure the update happens before the response is built. Updates in {% final %} run after the response is sent to the client.
:::
Related concepts
- Custom Data Mapping — defines which Salesforce fields are readable and writable from Liquid. The field must have a Custom Data Mapping created and marked Read/Write.
- Drop objects — the typed objects returned by globals like
current_product,current_order, andcurrent_customer. Records from{% query %}are untyped and must be cast first. - Controller lifecycle — the
{% before %},{% after %}, and{% final %}phases determine when code runs. Updates should happen in{% before %}or{% after %}, not{% final %}.
See Verify custom data in Liquid for a detailed walkthrough of reading and writing custom fields.
Was this article helpful?
Thanks for your feedback! It helps us improve our docs.