Skip to main content

Advanced Account Customization

Stuart Chaney avatar
Written by Stuart Chaney
Updated over 2 weeks ago

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 your widget translations and custom HTML. This guide will show you how to create personalized, data-driven experiences for your customers.

✨ All customer data is automatically available through the rivo_profile_customer Alpine.js store when customers view their account pages.


Understanding the Customer Data Store

Rivo exposes customer data through an Alpine.js store called rivo_profile_customer. This store is automatically populated when a customer views their account page and contains all their loyalty program information, preferences, and activity.

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 the complete structure of the customer object with example values:

{
  "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 HTML content (not just plain text), use rivo-ax-html:

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

⚠️ 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 internal Rivo ID

9552283369761

remote_id

Number

Customer's Shopify 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 phone number

"+1234567890"

phone_number

String/null

Alternate phone field

"+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

"17th Oct 2026"

lifetime_earnings_tally

Number/null

Total points earned all time

5000

Status & Tiers

Field

Type

Description

Example

loyalty_status

String

Current loyalty tier status

"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

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

15

referral_stats.claimed_count

Number

Sign-ups from referral link

5

referral_stats.completed_count

Number

Completed referrals (purchases)

3

Actions & Engagement

Field

Type

Description

Example

completed_custom_action_names

Array

Custom action names completed

["Follow on Instagram"]

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 console
console.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: The data is loaded when the account page loads and reflects the most recent information from the database.

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

A: No, the store is read-only. All customer data changes must go through Rivo's backend systems.

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

A: The store will either be empty or contain guest/anonymous customer data. Always handle empty 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: 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?