Skip to main content

Advanced Account Customization

Written by Stuart Chaney

Introduction

Rivo’s account widget provides a powerful way to customize the display of customer data using Alpine.js. You can dynamically insert customer information—like email, points balance, VIP tier, and more—directly into widget translations and supported custom HTML areas. This guide will show you how to create personalized, data-driven experiences for your customers.


✨ Signed-in customer data is available through the rivo_profile_customer Alpine.js store when customers view their account pages. Some fields load only after a widget section or API action requests them.




Understanding the Customer Data Store

Rivo exposes signed-in customer data through an Alpine.js store called rivo_profile_customer. The store is initialized when a customer views their account page, then updated as the widget loads loyalty balances, referral stats, VIP details, membership details, Shopify profile details, and other page-specific data.

Accessing the Store

You can access the store in two ways:

1. In JavaScript:

RivoProfileAlpine.store("rivo_profile_customer")

2. In HTML with Alpine directives:

<span rivo-ax-text="$store.rivo_profile_customer?.email"></span>

Available Customer Data

Here’s an example of the customer object with common values. Availability can vary by customer, enabled Rivo features, and which widget page has loaded.

{ "id": 9552283369761, "tags": ["Login with Shop", "Rivo VIP Tier: Gold", "Rivo Advocate"], "email": "[email protected]", "accepts_marketing": true, "first_name": "Jane", "last_name": "Smith", "orders_count": 12, "total_spent": 1450.75, "phone": "+1234567890", "addresses": [{ "address1": "123 Main St", "city": "San Francisco", "province": "CA", "zip": "94102" }], "status_points_tally": 1200, "status_credits_tally": "25.50", "account_activated_at": "2024-01-15T10:30:00.000Z", "referral_stats": { "clicked_count": 24, "claimed_count": 8, "completed_count": 5 }, "shop_id": 86674604321, "remote_id": 9552283369761, "points_tally": 1500, "credits_tally": 25.50, "dob": "05-15", "points_expiry": "17th Oct 2026", "completed_custom_action_names": ["Follow on Instagram", "Join Newsletter"], "loyalty_status": "vip", "loyalty_status_last_changed_at": "2025-11-03T22:19:02.000Z", "referral_url": "https://www.example.com?referral_code=LJdx6BLduxn16QeRz", "pretty_points_tally": "1,500", "pretty_credits_tally": "$25.50", "expected_points_tally": 1500, "lifetime_earnings_tally": 3200, "full_name": "Jane Smith", "phone_number": "+1234567890", "buyer_accepts_sms_marketing": true}



Using Alpine.js in Widget Translations

Basic Text Display

To display customer data in your widget translations, use the special rivo-ax-text attribute:

<span rivo-ax-text="$store.rivo_profile_customer?.email"></span>


💡 Why rivo-ax-text? We use a custom Alpine prefix (rivo-ax-) to avoid conflicts with other Alpine.js implementations on your store.


Displaying HTML Content

To render trusted HTML content (not just plain text), use rivo-ax-html:

<!-- This will render HTML tags --><div rivo-ax-html="$store.rivo_aw_translation?.featured_home_content"></div>

Some advanced custom HTML areas are enabled by Rivo. If you do not see the custom HTML option you need, contact Rivo Support.


⚠️ Security Warning: Only use rivo-ax-html with trusted content. Never use it with user-generated content that hasn't been sanitized, as it could introduce security vulnerabilities.


Common Display Patterns

Display Customer Email:

Welcome, <span rivo-ax-text="$store.rivo_profile_customer?.email"></span>!

Display Points Balance (Formatted):

You have <strong rivo-ax-text="$store.rivo_profile_customer?.pretty_points_tally"></strong> points

Display Credits Balance:

Your credit balance: <strong rivo-ax-text="$store.rivo_profile_customer?.pretty_credits_tally"></strong>

Display Customer Name with Fallback:

<span rivo-ax-text="$store.rivo_profile_customer?.full_name || 'Valued Customer'"></span>


📝 Tip: Use the || 'fallback' pattern to provide a default value when data is empty.




Advanced Alpine.js Directives

Conditional Display (rivo-ax-show)

Show or hide elements based on customer data:

Show message only if customer has points:

<div rivo-ax-show="$store.rivo_profile_customer?.points_tally > 0"> Congratulations! You have points to redeem.</div>

Show message only for VIP customers:

<div rivo-ax-show="$store.rivo_profile_customer?.tags.includes('Rivo VIP Tier: Gold')"> Welcome, Gold VIP Member! Enjoy your exclusive benefits.</div>

Show welcome message for new customers:

<div rivo-ax-show="$store.rivo_profile_customer?.orders_count === 0"> Welcome! Complete your first order to start earning points.</div>

Conditional Classes (rivo-ax-bind:class)

Apply CSS classes dynamically based on customer data:

<div rivo-ax-bind:class="$store.rivo_profile_customer?.points_tally > 1000 ? 'high-balance' : 'low-balance'"> Your balance: <span rivo-ax-text="$store.rivo_profile_customer?.pretty_points_tally"></span></div>

Loops (rivo-ax-for)

Loop through arrays of data:

Display completed action names:

<div rivo-ax-show="$store.rivo_profile_customer?.completed_custom_action_names.length > 0"> <h3>Completed Actions:</h3> <ul> <template rivo-ax-for="action in $store.rivo_profile_customer?.completed_custom_action_names"> <li rivo-ax-text="action"></li> </template> </ul></div>

Display customer tags:

<div> <h3>Your Tags:</h3> <template rivo-ax-for="tag in $store.rivo_profile_customer?.tags"> <span class="tag" rivo-ax-text="tag"></span> </template></div>



Complete Examples

Example 1: Personalized Welcome Banner

<div class="welcome-banner"> <h2> Welcome back, <span rivo-ax-text="$store.rivo_profile_customer?.full_name || $store.rivo_profile_customer?.email"></span>! </h2> <div class="stats"> <div class="stat"> <strong rivo-ax-text="$store.rivo_profile_customer?.pretty_points_tally"></strong> <span>Points</span> </div> <div class="stat"> <strong rivo-ax-text="$store.rivo_profile_customer?.orders_count"></strong> <span>Orders</span> </div> <div class="stat" rivo-ax-show="$store.rivo_profile_customer?.credits_tally > 0"> <strong rivo-ax-text="$store.rivo_profile_customer?.pretty_credits_tally"></strong> <span>Credits</span> </div> </div></div>

Example 2: VIP Tier Badge

<div class="tier-display" rivo-ax-show="$store.rivo_profile_customer?.tags.some(tag => tag.includes('Rivo VIP Tier:'))"> <template rivo-ax-for="tag in $store.rivo_profile_customer?.tags"> <span rivo-ax-show="tag.includes('Rivo VIP Tier:')" rivo-ax-text="tag.replace('Rivo VIP Tier: ', '')" class="vip-badge"> </span> </template></div>

Example 3: Referral Stats Dashboard

<div class="referral-stats"> <h3>Your Referral Performance</h3> <div class="stat-row"> <span>Link Clicks:</span> <strong rivo-ax-text="$store.rivo_profile_customer?.referral_stats.clicked_count"></strong> </div> <div class="stat-row"> <span>Sign-ups:</span> <strong rivo-ax-text="$store.rivo_profile_customer?.referral_stats.claimed_count"></strong> </div> <div class="stat-row"> <span>Completed Referrals:</span> <strong rivo-ax-text="$store.rivo_profile_customer?.referral_stats.completed_count"></strong> </div> <div class="referral-link"> <label>Your Referral Link:</label> <input type="text" readonly rivo-ax-bind:value="$store.rivo_profile_customer?.referral_url"> </div></div>

Example 4: Points Expiry Warning

<div class="expiry-warning" rivo-ax-show="$store.rivo_profile_customer?.points_expiry && $store.rivo_profile_customer?.points_tally > 0"> ⚠️ Your <strong rivo-ax-text="$store.rivo_profile_customer?.pretty_points_tally"></strong> points will expire on <strong rivo-ax-text="$store.rivo_profile_customer?.points_expiry"></strong>. <a href="/collections/all">Shop now to use them!</a></div>

Example 5: Conditional Messaging by Order Count

<!-- Message for new customers --><div rivo-ax-show="$store.rivo_profile_customer?.orders_count === 0"> <h3>🎉 Welcome to our loyalty program!</h3> <p>Place your first order to start earning points and unlock rewards.</p></div><!-- Message for returning customers --><div rivo-ax-show="$store.rivo_profile_customer?.orders_count > 0 && $store.rivo_profile_customer?.orders_count < 5"> <h3>Thanks for being a loyal customer!</h3> <p>You've placed <span rivo-ax-text="$store.rivo_profile_customer?.orders_count"></span> orders. Keep shopping to unlock VIP status!</p></div><!-- Message for VIP customers --><div rivo-ax-show="$store.rivo_profile_customer?.orders_count >= 5"> <h3>🌟 You're a VIP!</h3> <p>Thank you for your continued support with <span rivo-ax-text="$store.rivo_profile_customer?.orders_count"></span> orders!</p></div>



Field Reference

Basic Information

Field

Type

Description

Example

id

Number

Customer’s Shopify customer ID

9552283369761

remote_id

Number

Customer’s Shopify customer ID

9552283369761

email

String

Customer’s email address

first_name

String/null

Customer’s first name

"Jane"

last_name

String/null

Customer’s last name

"Smith"

full_name

String

Combined first and last name

"Jane Smith"

phone

String/null

Customer’s Shopify phone number, when Shopify profile details have loaded

"+1234567890"

phone_number

String/null

Customer phone number stored in Rivo

"+1234567890"

dob

String/null

Date of birth

"1990-01-01"

Points & Credits

Field

Type

Description

Example

points_tally

Number

Raw points balance

1500

pretty_points_tally

String

Formatted points balance

"1,500"

credits_tally

Number

Raw credits balance

25.50

pretty_credits_tally

String

Formatted credits with currency

"$25.50"

status_points_tally

Number

Points counting toward tier status

1200

status_credits_tally

String

Credits counting toward tier status

"20.0"

points_expiry

String/null

Date when points expire, when points expiry is enabled

"17th Oct 2026"

credits_expiry

String/null

Date when credits expire, when credits expiry is enabled

"17th Oct 2026"

lifetime_earnings_tally

Number/null

Total points earned all time, when this field is requested by the widget

5000

Status & Tiers

Field

Type

Description

Example

loyalty_status

String

Current customer loyalty status. This is not the customer’s specific VIP tier name.

"guest", "member", "vip"

loyalty_status_last_changed_at

String

Last status change timestamp

"2025-11-03T22:19:02.000Z"

tags

Array

All Shopify tags for this customer

["Rivo VIP Tier: Gold"]

Orders & Spending

Field

Type

Description

Example

orders_count

Number

Total number of orders

12

total_spent

Number

Lifetime spending amount from Shopify profile data

1250.00

Referral Program

Field

Type

Description

Example

referral_url

String

Customer’s unique referral link

"https://store.com?referral_code=ABC123"

referral_stats.clicked_count

Number

Times referral link was clicked, when referral stats have loaded

15

referral_stats.claimed_count

Number

Sign-ups from referral link, when referral stats have loaded

5

referral_stats.completed_count

Number

Completed referrals (purchases), when referral stats have loaded

3

Actions & Engagement

Field

Type

Description

Example

completed_custom_action_names

Array

Custom action names completed

["Follow on Instagram"]

completed_actions

Array

Completed earning action sources

["customer_member_enabled"]

expected_completed_actions

Array/null

Actions expected from a recent customer sync

["customer_member_enabled"]

social_actions

Array

Completed social earning actions

["instagram_follow"]

account_activated_at

String/null

When account was first activated

"2024-01-15T10:30:00.000Z"

Marketing & Preferences

Field

Type

Description

Example

accepts_marketing

Boolean

Email marketing opt-in status

true

buyer_accepts_sms_marketing

Boolean/null

SMS marketing opt-in status

false




Debugging Customer Data

View the Full Customer Object

To see all available data in your browser console:

console.log(JSON.stringify(RivoProfileAlpine.store("rivo_profile_customer"), null, 2));

Check if Data is Loaded

if (RivoProfileAlpine.store("rivo_profile_customer")) { console.log("Customer data loaded:", RivoProfileAlpine.store("rivo_profile_customer").email);} else { console.log("Customer data not yet loaded");}



Best Practices

1. Always Provide Fallbacks

Use the || operator to provide default values when data might be missing:

<span rivo-ax-text="$store.rivo_profile_customer?.full_name || 'Valued Customer'"></span>

2. Check Before Accessing Nested Properties

For nested objects, check existence first:

<div rivo-ax-show="$store.rivo_profile_customer?.referral_stats && $store.rivo_profile_customer?.referral_stats.completed_count > 0"> You have completed referrals!</div>

3. Use Semantic HTML

Wrap dynamic content in appropriate HTML elements:

<!-- Good --><strong rivo-ax-text="$store.rivo_profile_customer?.pretty_points_tally"></strong><!-- Avoid --><span style="font-weight: bold;" rivo-ax-text="$store.rivo_profile_customer?.pretty_points_tally"></span>

4. Prefer Pretty Fields for Display

Always use pretty_points_tally and pretty_credits_tally instead of raw values for user-facing displays:

<!-- Good - Formatted with commas and currency --><span rivo-ax-text="$store.rivo_profile_customer?.pretty_credits_tally"></span><!-- Avoid - Raw number without formatting --><span rivo-ax-text="$store.rivo_profile_customer?.credits_tally"></span>



Troubleshooting

Data Not Displaying

Symptom: Alpine directive shows nothing or displays the literal text

Check:

  • Verify you’re using rivo-ax- prefix (not x-)

  • Check browser console for JavaScript errors

  • Confirm customer is logged in

  • Verify the field exists in the customer object

Example Debug:

// In browser consoleconsole.log(RivoProfileAlpine.store("rivo_profile_customer"));

Null or Undefined Values

Symptom: Some fields show as blank or cause errors

Cause: Not all fields are populated for all customers

Fix: Always use fallbacks with ||:

<span rivo-ax-text="$store.rivo_profile_customer?.first_name || 'there'"></span>

Conditional Not Working

Symptom: rivo-ax-show doesn’t hide/show elements as expected

Check:

  • Verify the condition evaluates to a boolean

  • Use browser console to test the expression

  • Check for typos in field names

Array Methods Not Working

Symptom: .includes(), .some(), .filter() not working

Cause: Field might be null or not an array

Fix: Check array exists before using methods:

<div rivo-ax-show="$store.rivo_profile_customer?.tags && $store.rivo_profile_customer?.tags.includes('Rivo VIP')"> VIP Content</div>



Frequently Asked Questions

Q: Can I use regular Alpine.js directives (x-text, x-show)?

A: No, you must use the rivo-ax- prefix to avoid conflicts. Use rivo-ax-text, rivo-ax-show, etc.

Q: How often is customer data updated?

A: Basic customer data loads when the account page loads. Rivo refreshes loyalty balances and other details through widget API calls, and some fields only load when a related widget page or block opens.

Q: Can I modify the customer data from the frontend?

A: You can temporarily update the frontend store for display purposes, but those changes do not save customer data. Any real customer data change must go through a supported Rivo or Shopify action.

Q: What happens if a customer isn’t logged in?

A: The customer store will usually be empty. Always handle logged-out and missing-data states gracefully.

Q: Can I use this data outside the account widget?

A: The rivo_profile_customer store is only available within Rivo’s account widget pages. For other pages, use Rivo’s JavaScript SDK or API.

Q: Will account widget links automatically use the visitor’s current locale URL?

A: Only when Locale URL Rewriting is enabled for your Account Widget links. If your storefront uses regional URLs such as /fr-ca, enable Locale URL Rewriting so widget links point customers to the matching localized version of your store. Without it, links may keep their default URL path.

Q: Are there any performance concerns?

A: No, the customer data is small and loaded once per page. Alpine.js reactivity is efficient for this use case.




Getting Help

If you need assistance with advanced customizations:

  1. Check the data structure - Use JSON.stringify() in console to see exactly what’s available

  2. Test expressions - Run JavaScript expressions in browser console before adding to HTML

  3. Review Alpine.js docs - Visit https://alpinejs.dev for full directive documentation (remember to use rivo-ax- prefix)

  4. Contact Rivo Support - Email [email protected] with specific questions about your customization


💡 Pro Tip: Bookmark this page and keep the customer object structure handy for quick reference when building customizations!

Did this answer your question?