Configure Error Monitoring for Shopify
Features
Guide to configuring the analysis of impactful errors and filtering out the insignificant ones to Shopify Users or Business Processes. Ignore the noise and focus on the issues that are critical to your business! Germain has the ability to help you understand the impact, at scale, of any errors on the end-user or business operations while operating with Shopify. It helps separate critical errors from benign ones and also identifies the new ones.
![image-20240227-184050.png](../__attachments/3825827842/image-20240227-184050.png?inst-v=baad7441-1094-48da-b263-fa99f8ae5725)
Error on Shopify detected and analyzed by Germain UX
Enable User Error Monitoring for Shopify
Here is how to configure Germain UX’s monitoring to best detect and analyze errors that affect Shopify users.
Configure UX Monitoring Profile
Germain Workspace > Left Menu > Analytics > UX Monitoring Profiles > ShopifyUX Monitoring Profile for Shopify - Germain UX
Sample Code:
CODEgermainApm.native.XmlHttpRequest = XMLHttpRequest; // Work-around for sentry.io bocking our requests function getUsername(window) { return new germainApm.native.Promise(function (resolve, reject) { germainApm.utils.waitForProperty(window, 'ShopifyAnalytics', function () { if (window.ShopifyAnalytics) { if (window.ShopifyAnalytics.meta && window.ShopifyAnalytics.meta.page && window.ShopifyAnalytics.meta.page.customerId) { resolve(String(window.ShopifyAnalytics.meta.page.customerId)); } else if (window.ShopifyAnalytics.lib && window.ShopifyAnalytics.lib.trekkie && window.ShopifyAnalytics.lib.trekkie.defaultAttributes.uniqToken) { resolve(window.ShopifyAnalytics.lib.trekkie.defaultAttributes.uniqToken); } } resolve(null); }, function () { return reject(null); }, 20, 500); }); } function getSessionId(window) { return new germainApm.native.Promise(function (resolve, reject) { germainApm.utils.waitForProperty(window, 'ShopifyAnalytics', function () { if (window.localStorage && window.localStorage.session_id) { resolve(window.localStorage.session_id); } else if (window.ShopifyAnalytics && window.ShopifyAnalytics.lib && window.ShopifyAnalytics.lib.trekkie && window.ShopifyAnalytics.lib.trekkie.defaultAttributes.visitToken) resolve(null); }, function () { return reject(null); }, 20, 500); }); } function clickFactProcessor(fact, event, fireEvent, settings) { var target = event.target; if (target instanceof HTMLElement) { var name_1 = null; switch (target.nodeName) { case 'BUTTON': { if (target.id === 'continue_button') { name_1 = 'Cart Continue'; } else if (target.className) { var classNameTrimmed = target.className.trim(); if (classNameTrimmed === 'js-add-to-cart') { name_1 = 'Add To Cart'; } else if (classNameTrimmed === 'search-header__submit') { name_1 = 'Search'; } } break; } case 'INPUT': { var inputEvent = target; if (inputEvent.id === 'checkout_button') { name_1 = 'Checkout Now'; } else if (inputEvent.name === 'subscribe' && inputEvent.type === 'submit') { name_1 = 'Newsletter Subscription'; } else if (inputEvent.name === 'q' && inputEvent.type === 'search') { name_1 = 'Newsletter Subscription'; } else if (inputEvent.name === 'updates[]') { name_1 = 'Product Qty Changed'; } else if (inputEvent.className) { var classNameTrimmed = inputEvent.className.trim(); if (classNameTrimmed === 'cart-add') { name_1 = 'Add To Cart'; } } break; } case 'A': { var anchorTarget = target; if (anchorTarget.href && ~anchorTarget.href.indexOf('/cart/change?line=1&quantity=0')) { name_1 = 'Remove From Cart'; } else if (anchorTarget.className) { var classNameTrimmed = anchorTarget.className.trim(); if (classNameTrimmed === 'cart-table__content__remove') { name_1 = 'Remove From Cart'; } } break; } } if (name_1) { fact.name = name_1; germainApm.api.createEvent(name_1, { success: true, sequence: fact.sequence + '.' + 0 }); } } } function extractHierarchyDimensionFromAPI() { var shopifyWindow = window; if (shopifyWindow.ShopifyAnalytics && shopifyWindow.ShopifyAnalytics.meta && shopifyWindow.ShopifyAnalytics.meta.page && shopifyWindow.ShopifyAnalytics.meta.page.pageType) { return { level1: shopifyWindow.ShopifyAnalytics.meta.page.pageType, level2: shopifyWindow.ShopifyAnalytics.meta.product && shopifyWindow.ShopifyAnalytics.meta.product.type ? shopifyWindow.ShopifyAnalytics.meta.product.type : undefined // product type }; } return undefined; } function extractBusinessProcessFromAPI() { var shopifyWindow = window; if (shopifyWindow.ShopifyAnalytics && shopifyWindow.ShopifyAnalytics.meta && shopifyWindow.ShopifyAnalytics.meta.page) { if (shopifyWindow.ShopifyAnalytics.meta.page.resourceId) { return String(shopifyWindow.ShopifyAnalytics.meta.page.resourceId); } else if (shopifyWindow.ShopifyAnalytics.meta.page.pageType === 'searchresults' && window.location.search) { var match = window.location.search.match(/q=(.*)&/); if (match && match.length >= 2) { return match[1]; } } } return undefined; } function factProcessor(fact) { fact.hierarchy = extractHierarchyDimensionFromAPI(); fact.businessObject = extractBusinessProcessFromAPI(); } var settings = germainApm.getDefaultSettings(); settings.constants.logLevelToEmitAsFacts = 'WARN'; settings.application.metadataProviders['user.name'] = getUsername; settings.application.metadataProviders['sessionId'] = getSessionId; settings.application.factProcessor = factProcessor; settings.plugins.click.factProcessor = clickFactProcessor; settings.plugins.pageLoad.factProcessor = function (userClick, events) { for (var i = 0; i < events.length; i++) { if (events[i].event.type === 'document ready') { var page = events[i].page; if (page && page.title) userClick.name = 'Navigation ' + page.title; } } }; germainApm.eventGenerators.customAlert = { emits: ['DOM popup opening', 'DOM popup closed'], installer: function () { return function () { }; }, }; germainApm.start(settings);
Automate Identification of “new” errors
To be able to ignore the million of errors that occur every day and know when a new error occur, configure Germain UX’s Categorizationfeature.
Enable Alert and/or Report
Be alerted immediately when a new error occurs. Receive automatic report to help understand error volume trends.
Visualize & Analyze Shopify Errors
Add a portlet and set it up as following:
KPIs (any catching errors such as):
“Browser Event”
“Outbound Http Request”
(or any other KPI you have created in conjunction to monitoring errors).
Measures:
“Count”, “Count Unique User”, etc
Pivots:
”Name” or ”Message”
(depending on the KPI)
Filters:
”User Error” = “true” or “userError” = “true “
(depending the version of GermainUX you are on)
![image-20240227-184754.png](../__attachments/3825827842/image-20240227-184754.png?inst-v=baad7441-1094-48da-b263-fa99f8ae5725)
Add “JavaScript Popup Dialog” KPI for Shopify Error analysis - Germain UX
This is how the portlet would look like:
![image-20240227-184703.png](../__attachments/3825827842/image-20240227-184703.png?inst-v=baad7441-1094-48da-b263-fa99f8ae5725)
Shopify Error portlet - Germain UX
Exclude Errors
And once your portlet is created, you can always exclude/include additional errors, as following:Filter in or out specific Salesforce errors - Germain UX
Feature Availability: 2022.1 or later