Cross Device Baskets (aka. CDB & XDB)¶
Summary¶
Cross Device Baskets is a feature that allows customers to share their basket-items across multiple browsers & devices when they are logged into their Miva customer account.
Note
Logic only deals with active basket sessions, and does not work after baskets expire.
In short, it accomplishes this by sharing & merging the customer's g.Session_ID
field through some custom template code that manages the customer's cookies & basket details.
Setup / Installation¶
Note
The following modifications have been made on Genesis. However, for other existing stores, you can use the following steps to install it
- Upload the Toolbelt module on the domain, install the module on the Store, and ensure the
ry_toolbelt
item is assigned to all of the customer-facing pages. - Create a ReadyTheme Content Section
cross_device_baskets
to contain all of the application logic & modal views necessary to run the feature. - Add the
<mvt:item name="readytheme" param="contentsection( 'cross_device_baskets' )" />
to the top of the Global Header template code. - Assign the
customfields
item to all pages. - Changes the logout actions (ex.
<input type="hidden" name="Action" value="LOGO" />
) toCDB_LOGO
. - Code has been added
pages/Global.js
to handle displaying the modal to the customer.
Warn
If custom basket charges are used on the store, you may need to verify & make changes to that code to ensure charges are recalculated & not duplicated.
Test Cases¶
Sessions & Devices¶
- While you are logged into the same Miva customer account account, basket items should be shared across different browsers (ex. Chrome & Firefox)
- i.e. Test one session with basket contents that is logged in, then log in from another browser/device with an empty basket. This should simply resume the previous basket.
- While you are logged into the same Miva customer account account, Basket items should be shared within a browser that has two windows open: one in the regular mode & one in incognito mode
- Basket items should persist after logging out of an account and then logging back in on the same account on the same browser.
Functionality¶
- With baskets contents in one logged in session, add items to another session, and then log into the same account to trigger the basket handling choices.
- Test all 3 choices options + the additional wish list choice options if they are choosing to use those.
- Ensure baskets are being deleted when the choice is made not to use them (use current deletes the previous, and vise versa). When testing merge option, test with a variety of basket content scenarios and items. Items with attributes, variants, coupons, basket custom fields (if you've customized their integration for - custom fields).
- Test failing to make a decision on one browser and taking action again on another.
- Test all logout options on the store to ensure they've been updated to CDB_LOGO and behavior properly by existing that session entirely.
Features & Modifications¶
Basket Merging¶
When a customers login, it can be setup to show options to the customer about how they would like to handle their baskets. These are the customer's options:
- Merge the previous & current session's basket items together
- Use the previous session's basket items
- Use the current session's basket items
- Save previous session's basket items to a wishlist and continue shopping with the current session's items
- Save current session's basket items to a wishlist and continue shopping with the previous session's items
For Genesis, we have chosen to default to merging the basket items together automatically without giving the customer a choice. We believe this is the most-seamless & industry standard experience for the customers.
However, if you would like to give the customers a choice, update the cross_device_basket
ReadyTheme Content Section so that the l.allow_choice_on_login
variable is set to 1
at the top. Setting this variable to 1
(truthy) will show the modal to the customer and setting it to 0
(falsy) will not show the modal and trigger the CDB_Merge
action automatically instead.
How to Disable¶
If you do not want the store to have this feature enabled by default, then you can do the following:
- De-activate the
cross_device_baskets
ReadyTheme Content Section. - Revert the
CDB_LOGO
actions back to Miva's defaultLOGO
action. - Remove the modal JavaScript from
pages/Global.js
- Optionally, uninstall Toolbelt
- Unassign the
ry_toolbelt
item from all pages - Delete the
ry_toolbelt
item - Uninstall the Toolbelt module.
- Unassign the
Custom Functionality for Basket Custom Fields¶
Sometimes the Cross Device Baskets feature will need to be extended to ensure that client-specific custom-functionality continues to work. This can occur if the functionality relies on Basket Custom Fields that need to be maintained in certain ways as sessions are merged/restore.
If you have to manage basket custom-fields in specific ways, then you'll probably need to add it into the cross_device_baskets
ReadyTheme Content Section where it says:
@@ ADD CUSTOM BAKET CUSTOM-FIELD LOGIC HERE @@
Example Code¶
The following example shows what kind of logic needed to be added to Plant Therapy to maintain their Add-on Product & Add-on Price Group feature.
<mvt:comment>
|
| EXAMPLE from PT: Custom Addon CustomField Handling
|
| Load current basket's addon custom fields.
| Loop through last basket's custom fields.
| If current basket has the addon custom fields, then combine the values.
| If current basket does NOT have the addon custom fields, then just update with the last basket's values.
|
</mvt:comment>
<mvt:item name="customfields" param="Read_Basket( 'addonProducts', l.settings:addonProducts )" />
<mvt:item name="customfields" param="Read_Basket( 'addonPriceGroups', l.settings:addonPriceGroups )" />
<mvt:foreach iterator="customfield" array="last_basket_customfields">
<mvt:if expr="l.settings:customfield:code EQ 'addonProducts'">
<mvt:if expr="l.settings:addonProducts NE ''">
<mvt:foreach iterator="last_addon_product" array="customfield:value">
<mvt:assign name="l.index" value="miva_array_insert_var( l.settings:addonProducts, l.settings:last_addon_product, -1 )" />
</mvt:foreach>
<mvt:else>
<mvt:assign name="l.settings:addonProducts" value="l.settings:customfield:value" />
</mvt:if>
</mvt:if>
<mvt:if expr="l.settings:customfield:code EQ 'addonPriceGroups'">
<mvt:if expr="l.settings:addonPriceGroups NE ''">
<mvt:foreach iterator="last_addon_pricegroup" array="customfield:value">
<mvt:if expr="NOT (l.settings:last_addon_pricegroup CIN l.settings:addonPriceGroups)">
<mvt:assign name="l.index" value="miva_array_insert_var( l.settings:addonPriceGroups, l.settings:last_addon_pricegroup, -1 )" />
</mvt:if>
</mvt:foreach>
<mvt:else>
<mvt:assign name="l.settings:addonPriceGroups" value="l.settings:customfield:value" />
</mvt:if>
</mvt:if>
</mvt:foreach>
<mvt:do file="g.Module_Root $ l.cfmod:module" name="l.success" value="Module_Basket_Set_Field( l.cfmod, l.settings:last_basket:basket_id, 'addonProducts', l.settings:addonProducts )" />
<mvt:do file="g.Module_Root $ l.cfmod:module" name="l.success" value="Module_Basket_Set_Field( l.cfmod, l.settings:last_basket:basket_id, 'addonPriceGroups', l.settings:addonPriceGroups )" />