Developer guide

Add LensAdvisor to your Shopify theme, customize the lens flow, and connect your systems to the API.

01 · Installation

Add LensAdvisor to your theme

Choose the instructions for your Shopify theme. Online Store 2.0 themes use app blocks. Older themes need a Liquid snippet.

Online Store 2.0

  1. Open your product template in the Shopify theme editor.
  2. Add the LensAdvisor Select Lenses app block, then save the template.
  3. Check the cart integration so frame and lens quantities stay together.

Add a Quick Buy button

Use Quick Buy on collection pages, the homepage, or custom sections.

  1. Turn on the LensAdvisor Quick Buy app embed.
  2. Add this component where a Shopify product object is available.
liquid
<lensadvizor-quick-buy
    class="la-select-lenses-btn"
    data-la-quick-buy
    data-la-product-id="{{ product.id }}"
    data-la-variant-id="{{ product.selected_or_first_available_variant.id }}"
    data-la-product-json="{{ product | json | escape }}"
    data-la-flow-id=""
>
</lensadvizor-quick-buy>

Older Shopify themes

  1. Download the lensadvizor.liquid snippet.
  2. Add the file to your theme’s snippets folder.
  3. Add this code to layout/theme.liquid to load it on product and cart pages.
liquid
<!-- LensAdvizor snippet starts -->
{% if request.page_type == 'product' or request.page_type == 'cart' %}
  {% render 'lensadvizor' %}
{% endif %}
<!-- LensAdvizor snippet ends -->

Hide the lens button on a product

Add the remove-rx tag to the product to hide its Select Lenses button.

Tip

For dynamically loaded Quick Buy buttons, add data-la-quick-view="1" to the component. You can also call LensAdvizor.init() after inserting it.

02 · Events

Run code when the lens flow changes

LensAdvisor dispatches JavaScript events on document. Use these events to track flow steps or customize the interface.

Listen for a flow step

Add your JavaScript in LensAdvisor under Settings, then Advanced: Custom JS.

This example runs when LensAdvisor shows the prescription type selector.

js
document.addEventListener('LensAdvizor:prescriptionTypes:rendered', () => {
  // Add your code for this step here.
});

Connect a cart drawer

To keep customers on the product page, connect LensAdvisor to your theme’s cart drawer.

  1. In LensAdvisor settings, turn on Advanced: Add to Cart Custom Event.
  2. Define LensAdvizor.postAddToCart in your custom JavaScript.
  3. Use your theme’s cart methods inside the function to refresh and open the drawer.

LensAdvisor calls this function after adding the selected products to the cart.

js
LensAdvizor.postAddToCart = async () => {
  // Refresh and open the cart drawer using your theme's methods.
};
Note

Keep the LensAdvizor spelling in event names and JavaScript objects. The code identifiers use a “z”.

Storefront event reference

Listen for the event that matches the step you need. The lens-rendered event includes the step name in e.detail.method.

js
document.addEventListener('LensAdvizor:init:start', function() {});
document.addEventListener('LensAdvizor:init:complete', function() {});
document.addEventListener('LensAdvizor:init:error', function() {});

document.addEventListener('LensAdvizor:variant:change', function() {});
document.addEventListener('LensAdvizor:lensVariant:change', function() {});

document.addEventListener('LensAdvizor:selectLensModal:open', function() {});
document.addEventListener('LensAdvizor:selectLensModal:close', function() {});

document.addEventListener('LensAdvizor:prescriptionTypes:rendered', function() {});

document.addEventListener('LensAdvizor:render:contactLens', function() {});

document.addEventListener('LensAdvizor:render:submissionMethods', function() {});

document.addEventListener('LensAdvizor:render:uploadForm', function() {});
document.addEventListener('LensAdvizor:render:readingForm', function() {});
document.addEventListener('LensAdvizor:render:manualEntryForm', function() {});

document.addEventListener('LensAdvizor:lens:rendered', function() {});
document.addEventListener('LensAdvizor:lens:rendered', function(e) {

// check e.detail.method for step
});

document.addEventListener('LensAdvizor:lens:rendered', function(e) {
    if (e.detail.method == 'renderLensGroup') {
        // handle renderLensGroup
    }
    if (e.detail.method == 'renderLenses') {
        // handle renderLenses
    }
});

document.addEventListener('LensAdvizor:lensOptions:rendered', function() {});
document.addEventListener('LensAdvizor:lensOption1:rendered', function() {});
document.addEventListener('LensAdvizor:lensOption2:rendered', function() {});
document.addEventListener('LensAdvizor:lensOption3:rendered', function() {});

document.addEventListener('LensAdvizor:addOns:rendered', function() {});

document.addEventListener('LensAdvizor:review:rendered', function() {});

document.addEventListener('LensAdvizor:action:exception', function() {});

document.addEventListener('LensAdvizor:addToCart:success', function() {});
document.addEventListener('LensAdvizor:addToCart:error', function() {});

document.addEventListener('LensAdvizor:prescription:updated', function() {});
document.addEventListener('LensAdvizor:toolTip:open', function() {});
document.addEventListener('LensAdvizor:Cart:Stable', function() {});
document.addEventListener('LensAdvizor:Cart:Updated', function() {});
03 · API

Connect to the Customer and Orders API

API access is available on Pro and higher plans. Use the API reference for endpoints, request fields, and response formats.

Set up API access

  1. Open Settings in LensAdvisor.
  2. Find the access token section and generate a token.
  3. Follow the authentication instructions in the Customer and Orders API reference.

Requests use the X-LensAdvizor-Access-Token and X-LensAdvizor-Shop headers. The shop value is your store’s myshopify.com domain.

Access

Keep the access token on your server. Do not include it in theme code or browser JavaScript.

04 · Metafields

Configure flows with metafields

Shopify metafields store product and collection settings. LensAdvisor metadata stores values on flows, lenses, and other items in the flow editor.

Shopify metafields

Edit Shopify metafields under Settings, then Custom data. These fields use the lensadvisor namespace.

  • collection_id: assigns a lens flow to products in a collection.
  • options: sets product-specific prescription form options, including pupillary distance (PD), sphere, and segment height.
  • _assigned_variants: stores variant assignments managed by LensAdvisor.
  • BASE_URL and _global_settings: store app settings managed by LensAdvisor.

Use LensAdvisor to change app-managed fields.

Set prescription form options

This example shows a JSON value for the product metafield lensadvisor.options. Adjust the values to match your requirements.

json
{
  "prescriptionConfig": {
    "fieldOptions": {
      "pd":            { "min": "50", "max": "72", "steps": "0.5", "defaultValue": "64" },
      "dualPd":        { "min": "25", "max": "36", "defaultValue": "32" },
      "sph":           { "min": "-4.00", "max": "2.00" },
      "segmentHeight": { "defaultValue": "16" }
    },
    "segmentHeight":         "hidden",
    "segmentHeightOnUpload": "hidden"
  }
}

Add metadata in LensAdvisor

In the flow editor, open the three-dot menu beside an item and select Edit metafields.

Add each value as a key and value pair. Use metadata for custom flow behavior or order fulfillment.

Common metadata keys include:

  • _showRecommendationBadge: shows a recommendation badge when set to true
  • toolTip: adds help text to a lens or lens group
  • picture_matrix: sets frame and lens preview images
  • addon_flow: assigns an additional lens flow to a prescription type
Note

Metadata keys beginning with _ are hidden from the LensAdvisor Orders view. Use them for settings that staff do not need when processing orders.

05 · Code examples

Customize the storefront

Use these examples in LensAdvisor’s custom JavaScript settings. Replace placeholder values and selectors to match your store.

01 Track flow steps in Google Analytics

Connect Google Analytics 4 (GA4) before adding this example. It sends a page-view event when a customer reaches each flow step.

// ---Setup tracking of Virtual Pageviews for Google Analytics 4--- 
document.addEventListener('LensAdvizor:prescriptionTypes:rendered', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/select_prescription_type' });
});
document.addEventListener('LensAdvizor:render:submissionMethods', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/select_prescription_method' });
});
document.addEventListener('LensAdvizor:render:uploadForm', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/enter_prescription_uploaded' });
});
document.addEventListener('LensAdvizor:render:manualEntryForm', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/enter_prescription_manually' });
});
document.addEventListener('LensAdvizor:lens:rendered', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/choose_lens' });
});
document.addEventListener('LensAdvizor:lensOptions:rendered', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/choose_options' });
});
document.addEventListener('LensAdvizor:addOns:rendered', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/choose_addons' });
});
document.addEventListener('LensAdvizor:review:rendered', function(){
    gtag('event', 'page_view', { 'page_path': '/lensadvisor/review_selection' });
});
02 Read the customer’s selections

LensAdvizor.response stores the customer’s selections as they move through the flow. Read it after the relevant step event.

03 Read metadata in JavaScript

After the flow opens, read flow and prescription type metadata from these objects:

  • LensAdvizor.options.flowMetafields
  • LensAdvizor.prescriptionTypes[n].metafields

After lenses load, use these objects:

  • LensAdvizor.lensGroups[n].metafields
  • LensAdvizor.lenses[n].metafields
  • LensAdvizor.lenses[n].raw_options[n].metafields
  • LensAdvizor.lenses[n].add_ons_products[n].metafields

Replace n with the index of the item you need.

04 Set metadata for a lab integration

Lab metadata tells the lab which materials, coatings, and other options to use for an order.

A value set on a lens option overrides the same key set on its parent lens.

Use the optical lab integration guide for your lab’s metadata keys and setup instructions.

05 Add text beside PD fields

Add help text after the pupillary distance fields. Replace the example HTML with your message.

// ADD PD TEXT
// Upload Form
document.addEventListener('LensAdvizor:render:uploadForm', function(){
	document.querySelector("#la-pd-fields-container").insertAdjacentHTML("afterend", "<br><p>Inserted Custom HTML</p>")
})
// Reading Form
document.addEventListener('LensAdvizor:render:readingForm', function(){
	document.querySelector("#la-pd-fields-container").insertAdjacentHTML("afterend", "<br><p>Inserted Custom HTML</p>")
})
// Manual Entry Form
document.addEventListener('LensAdvizor:render:manualEntryForm', function(){
	document.querySelector("#la-pd-fields-container").insertAdjacentHTML("afterend", "<br><p>Inserted Custom HTML</p>")
})
06 Add a required confirmation checkbox

This example adds a required checkbox to the manual prescription form.

document.addEventListener('LensAdvizor:render:manualEntryForm', function(){
  document.querySelector('[data-form=manually] .la-upload-wrapper').insertAdjacentHTML("afterend",`
    <div class='la-rx-verify'> 
      <input type='checkbox' id='la-rx-verify-checkbox' required> 
      <label for='la-rx-verify-checkbox' class='la-rx-verify-label'>
        I confirm I've entered my prescription correctly.
      </label>
    </div>
  `)
})
07 Add a custom tooltip

Replace the example title, content, image URL, and selector with your own values.

// First get the layout
let tooltipData = {
    "title":"Tooltip Title",
    "content": "Tooltip Content HTML <h1>awesome</h1>"
}
// imgSrc is optional. If omitted the default image will be used
customToolTipLayout = LensAdvizor.getToolTipLayout(tooltipData, '<imgSrc>')
// insert the tooltip into the HTML
document.querySelector('.some-class').insertAdjacentHTML('afterend', customToolTipLayout)
08 Change the back and close button images

Replace each image URL with the image you want to show.

// Change the default back and close buttons
document.addEventListener('LensAdvizor:prescriptionTypes:rendered', function(){
	document.querySelector('.la-steeper-back img').src = '<imgURL>'
	document.querySelector('.la-prescription-modal-close img').src = '<imgURL>'
})
09 Change flow icons
 // Changing icons
document.addEventListener('LensAdvizor:init:complete', function(){
	LensAdvizor.svg.upload = '<svg code>'
})

Icons available to change:

  • LensAdvizor.svg.upload
  • LensAdvizor.svg.edit
  • LensAdvizor.svg.email
  • LensAdvizor.svg.attachment
  • LensAdvizor.svg.check
  • LensAdvizor.svg.tooltip
  • LensAdvizor.svg.preview
  • LensAdvizor.svg.doc
  • LensAdvizor.svg.onfile
  • LensAdvizor.svg.camera
10 Add lens properties with an HTML input

Use an input named la-properties[name] to add a lens line-item property. Replace name with your property name.

document.addEventListener('LensAdvizor:prescriptionTypes:rendered', function(){
    // When the Prescription Types are created, add in the hidden input(s)
    hiddenInputText = `
      <input id="hiddenTryOnProperty" type="hidden" name='la-properties[Try On]' value="Yes" >
    `
    wrapper = document.querySelector('.la-prescription-modal-wrapper')
    wrapper.insertAdjacentHTML('beforeend', hiddenInputText)    
})
11 Add line-item properties with JavaScript

Add key and value pairs to the object for each product type:

  • frame: LensAdvizor.customBaseProductProperties
  • lenses: LensAdvizor.customLensProperties
  • add-ons: LensAdvizor.customAddOnsProperties
12 Add a custom add-on product

Add a product to LensAdvizor.customAddOns. Replace the example product, variant, price, and step values with your own.

 // ADD A Custom Add On product 
	LensAdvizor.customAddOns.push({
		productId: 12345678901234, // Change to desired Product ID
		variantId: 12345678901234,// Change to desired variant ID of Product
		step: "Example Step",
		productTitle: "Example - $19 Extra",
		price: 19,
		properties: {}
	})

Use this helper to remove an add-on by its step name.

 // Helper fuction to remove step by name
 var removeCustomAddOnStep = function(stepName){
    const indx = LensAdvizor.customAddOns.findIndex(v => v.step === stepName);
    LensAdvizor.customAddOns.splice(indx, indx >= 0 ? 1 : 0);
  }
Integration support

Get help with your integration

Talk to our team about a custom theme, lab integration, or migration to LensAdvisor.

Book an integration call