Link Search Menu Expand Document

Data binding

We provide a way to output dynamic customer data to a page without needing to use JavaScript with the tinybind library as an alternative to using metafields.

When to use data binding instead of Liquid?

In certain use-cases, developers need to collect guest data. Guest data, is data that has been stored in the browser’s localStorage for usage throughout the session without needing to login or register the customer for an account.

If the customer isn’t logged in, the customer object won’t be available in Liquid, so you can’t access any of that information without using JavaScript. Data binding fills in the gap here by allowing developers to still write templates and other logic in the markup, with the added benefit of having access to guest data. If the customer is logged in, any saved data will also be pulled into the template.

Shout out to Cart.js for giving us the inspiration to offer a Rivets implementation, from having an elegant experience working with it on client projects in the past.

What is tinybind?

tinybind (a successor to Rivets.js), is a lightweight data binding and templating system that facilitates building data-driven views and can be used to output customer data into the document. The main reason we added this to the JS Customer API is so that guest data can still be used while writing markup, for example:

<div data-cf-view>
  <div rv-if="customer.first_name">
    <h1>Welcome back, {customer.first_name}!</h1>
  </div>

  <div rv-unless="customer_logged_in">
    Hey there! 
  </div>
</div>

Getting started

Ensure you have installed a form on the theme you’re working with. We recommend creating a form called something like: “Custom development”, then installing it with only the “Other location” box ticked so our snippet and assets get added.

Add this to the <head> inside your layout/theme.liquid:

{% render 'customer-fields', customer_api: true, version: '<Version number>' %}

Now you’re ready to add customer data to the page.

Adding customer data to a page

There are different ways to interpolate text into the document using tinybind. Here’s one example:

<div data-cf-view>
  <h1>Hello there, {customer.first_name}!</h1>
</div>

Sometimes the above example isn’t very preferable, since tinybind is loaded asynchronously on the page causing customers to sometimes see “{customer.first_name}” in plain text until it is initialized.

Here’s another approach that can solve that problem, with one drawback of being a bit more verbose:

<div data-cf-view>
  <h1>Hello there, <span rv-text="customer.first_name"></span>!</h1>
</div>

Conditionally render and bind values to attributes

The power of tinybind shines through a concept called binders. The previous example actually uses one called rv-text, which binds the value of customer.first_name to the text of the <span> element. There are many other built-in binders that ship with tinybind, a few of them will be documented below but you can view the full list in their docs.

rv-if

Conditionally renders the element that the binder is attached to based on whether or not the value passed to it is truthy.

<div data-cf-view>
  <h1 rv-if="customer.first_name">Hello, {customer.first_name}!</h1>
</div>

The above example only renders a greeting if the customer has a first_name.

rv-unless

Conditionally renders the element that the binder is attached to unless the value passed to it is truthy.

<div data-cf-view>
  <a rv-unless="customer.id" href="/account/login">Please log in</a>
</div>

The above example renders a login link unless the customer has an id (which is only present if logged in.)

rv-each-[item]

Repeat the element for each <item> in the value passed to it.

For this example, let’s assume we have a group_list data column called wishlist that contains objects with keys url and title:

<div data-cf-view>
  <ul>
    <li rv-each-product="customer.wishlist">
      <a rv-href="product.url" rv-text="product.title"></a>
    </li>
  </ul>
</div>

Notice how we’ve replaced [item] with product, allowing us to reference each iterated item as product

rv-[attribute]

Binds a value to any HTML attribute, assuming the specified attribute doesn’t conflict with an existing binder.

<div data-cf-view>
  <div rv-data-customer-name="customer.first_name"></div>
</div>

If the customer has a first_name of "John", will produce the following markup:

<div data-cf-view>
  <div data-customer-name="John"></div>
</div>

Example data

We bind an object with the following properties:

{
  "customer": {
    "first_name": "Greg",
    "last_name": "Rivers",
    "email": "greg@gmail.com"
  },
  "customer_logged_in": false,
  "customer_saving": true,
  "customer_saved": false,
  "redirecting": false,
  "has_errors": true,
  "errors": {
    "email": ["is invalid"]
  }
}

Formatters

We’ve added a standard library of common Rivets formatters. You can use these within the context of a data-cf-view.

View formatters


Have any questions or comments about this post? Let us know! Your feedback is greatly appreciated.

Customer Fields is a Shopify app made by Helium.

Copyright © 2020 Helium Development, LLC