{"id":1167,"date":"2025-04-17T14:48:02","date_gmt":"2025-04-17T18:48:02","guid":{"rendered":"https:\/\/www.digitaldatatactics.com\/?p=1167"},"modified":"2025-09-02T14:21:02","modified_gmt":"2025-09-02T18:21:02","slug":"the-rule-sandwich-now-for-the-websdk","status":"publish","type":"post","link":"https:\/\/www.digitaldatatactics.com\/index.php\/2025\/04\/17\/the-rule-sandwich-now-for-the-websdk\/","title":{"rendered":"The Rule Sandwich: now for the webSDK!"},"content":{"rendered":"\n<p><em>(Note: this was originally published March 2025 on <a href=\"https:\/\/www.33sticks.com\/articles\/the-rule-sandwich-now-for-the-websdk\" data-type=\"link\" data-id=\"https:\/\/www.33sticks.com\/articles\/the-rule-sandwich-now-for-the-websdk\">the 33 sticks blog<\/a>.)<\/em><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignright size-full is-resized\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2024\/02\/image-11.png\"><img loading=\"lazy\" decoding=\"async\" width=\"705\" height=\"590\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2024\/02\/image-11.png\" alt=\"\" class=\"wp-image-998\" style=\"width:435px;height:auto\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2024\/02\/image-11.png 705w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2024\/02\/image-11-300x251.png 300w\" sizes=\"(max-width: 705px) 100vw, 705px\" \/><\/a><\/figure><\/div>\n\n\n<p>I\u2019ve <a href=\"https:\/\/www.digitaldatatactics.com\/index.php\/2024\/02\/09\/the-adobe-launch-rule-sandwich\/\" target=\"_blank\" rel=\"noreferrer noopener\">written previously<\/a> about what I\u2019ve found to be the most scaleable method of implementing analytics in Adobe Launch*, but that was for the old Analytics\/appMeasurement way of doing things. If you\u2019re using the webSDK, the Rule Sandwich is still an option, though it works slightly differently (and is a little less intuitive, IMO).<\/p>\n\n\n\n<p>Before I tell you how, I highly recommend reading that previous <a href=\"https:\/\/www.digitaldatatactics.com\/index.php\/2024\/02\/09\/the-adobe-launch-rule-sandwich\/\" target=\"_blank\" rel=\"noreferrer noopener\">Rule Sandwich post<\/a>, but if not, at a high level, the idea behind the \u201crule sandwich\u201d is to have:<\/p>\n\n\n\n<p>1. one rule that fires everywhere, that sets all your global variables- things that follow the same logic everywhere, and belong on every (applicable) event, such as login state, site section, marketing campaign\u2026<\/p>\n\n\n\n<p>2. a set of rules specific to particular user actions (a product details page view, a form submission, etc) where you set variables that should only be set with that user action<\/p>\n\n\n\n<p>3. potentially a third rule to fire the event\/beacon off to Adobe.<\/p>\n\n\n\n<p>The goal is to reduce redundancy and create something that scales. If page name is ALWAYS going to come from the same place in the data layer, there is no reason to configure that over and over. If I need to make an update to one variable, I don\u2019t want to do it in a bunch of different rules.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The \u201cStandard\u201d webSDK Implementation: map your XDM Object<\/h2>\n\n\n\n<p>The \u201cdefault\u201d way (and for a long time, the <em>only<\/em> way) to setup your webSDK payload was to have a single \u201cXDM Object\u201d data element that mapped <em>everything<\/em>. <a href=\"https:\/\/experienceleague.adobe.com\/en\/docs\/analytics-platform\/using\/compare-aa-cja\/upgrade-to-cja\/create-tags\/cja-upgrade-tag-xdm\" target=\"_blank\" rel=\"noreferrer noopener\">Adobe\u2019s documentation walks through how to do this<\/a>. There is one big problem, though: some XDM fields (like anything you\u2019d base a metric on) should only be set in certain situations- for example, I only want my Internal Search Input metric to increment \u201c1\u201d on the Internal Search Results page. If I had a single Data Element that handled all of my XDM set up, how do I tell it to only set _experience.analytics.event1to100.event5.value to \u201c1\u201d when the user is on a Search Results page? You could:<\/p>\n\n\n\n<ol>\n<li>Have a data element for every metric, so you could use script to dynamically fill in that XDM field. If I have 50 events, that means I might have 50 data elements that each look something like this (or possibly more complicated depending on your conditions) :<\/li>\n<\/ol>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-js\" data-lang=\"JavaScript\"><code>if(_satellite.getVar(&quot;DDT: page type&quot;)==&quot;search results&quot;){\n     return 1\n}<\/code><\/pre><\/div>\n\n\n\n<p>\u2026and then in your XDM Object Data Element, you\u2019d do something like this for every one of your event fields:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmObjectMetric.png\"><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"572\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmObjectMetric.png\" alt=\"\" class=\"wp-image-1168\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmObjectMetric.png 838w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmObjectMetric-300x205.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmObjectMetric-768x524.png 768w\" sizes=\"(max-width: 838px) 100vw, 838px\" \/><\/a><\/figure>\n\n\n\n<ol start=\"2\">\n<li>You could create a separate XDM object for each situation. For example, you\u2019d have a \u201cSearch Results\u201d rule that pulls in your \u201cSearch Results\u201d XDM Object Data Element, which has all your global variables, plus your internal-search-specific logic. Then you\u2019d have another \u201cProduct Details Page\u201d rule that pulls in your \u201cProduct Details Page\u201d XDM Object Data Element, which also has all your global variables, and so forth.<\/li>\n\n\n\n<li>You don\u2019t set your situation-specific stuff in Launch at all, and instead use Data Prep to do something like this:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/eventMapping.png\"><img loading=\"lazy\" decoding=\"async\" width=\"830\" height=\"118\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/eventMapping.png\" alt=\"\" class=\"wp-image-1169\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/eventMapping.png 830w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/eventMapping-300x43.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/eventMapping-768x109.png 768w\" sizes=\"(max-width: 830px) 100vw, 830px\" \/><\/a><\/figure>\n\n\n\n<p>I really dislike all three of these options, though if I had to choose, I\u2019d go with the first. Fortunately, Adobe provided another way: <strong>Update Variable<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">A better option: Update Variable<\/h3>\n\n\n\n<p>To use Update Variable, you first need to create a webSDK Data Element of the type \u201cVariable\u201d:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmVariable.png\"><img loading=\"lazy\" decoding=\"async\" width=\"870\" height=\"508\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmVariable.png\" alt=\"\" class=\"wp-image-1170\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmVariable.png 870w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmVariable-300x175.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/xdmVariable-768x448.png 768w\" sizes=\"(max-width: 870px) 100vw, 870px\" \/><\/a><\/figure>\n\n\n\n<p>This is a little unique, since it\u2019s a Data Element that doesn\u2019t really <em>return<\/em> something that you\u2019d want to use, but rather just gives you abilities within your Rule Actions. The Data Element is mainly just to give you a place to specify the schema you want to follow.<\/p>\n\n\n\n<p>Then you create rules with varying scopes, to \u201cupdate the variable\u201d as needed. At this point, you can think of it the same way you\u2019d think of the Analytics \u201cSet Variable\u201d action (which can really help with migration, by the way- you can \u201cmigrate\u201d one \u201cSet Variables\u201d at a time).<\/p>\n\n\n\n<p>So, to make my rule sandwich, I\u2019d start with a Global rule I want firing on all my events. The tricky part is covering all the different types of triggers that might fire tracking. If you\u2019re using the ACDL extension, and not listening to any clicks or anything, then this is easy-peasy. But often it\u2019ll end up being some combo of data layer events and clicks (and again, this is discussed in <a href=\"https:\/\/www.digitaldatatactics.com\/index.php\/2024\/02\/09\/the-adobe-launch-rule-sandwich\/#globalVars\" target=\"_blank\" rel=\"noreferrer noopener\">my previous Rule Sandwich post<\/a>).<\/p>\n\n\n\n<p>I\u2019d give the trigger(s) a low \u201corder\u201d number (like 1, or 25\u2026 it\u2019s all relative, just needs to be lower that my other rules). I\u2019d create an action using the WebSDK\u2019s \u201cUpdate Variable\u201d Action Type:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/globalRule.png\"><img loading=\"lazy\" decoding=\"async\" width=\"761\" height=\"613\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/globalRule.png\" alt=\"\" class=\"wp-image-1171\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/globalRule.png 761w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/globalRule-300x242.png 300w\" sizes=\"(max-width: 761px) 100vw, 761px\" \/><\/a><\/figure>\n\n\n\n<p>When I first open that \u201cUpdate Variable\u201d action, it will have me specify which variable I want to update, so I select the Data Element I just created. It will then create an XDM tree that matches your schema, very similar to an \u201cXDM Object\u201d Data Element. It even includes some helpful info, about how to tell what has been populated and how to clear out all or part of your variables as needed (which is important- we\u2019ll get back to that later).<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/updateVariableActionBlurb.png\"><img loading=\"lazy\" decoding=\"async\" width=\"809\" height=\"369\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/updateVariableActionBlurb.png\" alt=\"\" class=\"wp-image-1172\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/updateVariableActionBlurb.png 809w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/updateVariableActionBlurb-300x137.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/updateVariableActionBlurb-768x350.png 768w\" sizes=\"(max-width: 809px) 100vw, 809px\" \/><\/a><\/figure>\n\n\n\n<p>Since this is our global rule, I\u2019d go through and set every field I have that should always fire, provided its data element has a value (login state, page name*, internal\/external campaign tracking codes, etc).<\/p>\n\n\n\n<p>*Note with Page Name and URL, you may not want to set that globally, particularly if this data is still bound for Adobe Analytics. Analytics bases whether or not it consider an event a \u201cpage view\u201d (equivalent to an s.t() beacon) <a href=\"https:\/\/experienceleague.adobe.com\/en\/docs\/analytics\/implementation\/aep-edge\/overview#:~:text=and%20link%20events%3A-,XDM%20payload%20contains,-%E2%80%A6\" target=\"_blank\" rel=\"noreferrer noopener\">based on several factors, including the presence of URL or<\/a><a href=\"https:\/\/experienceleague.adobe.com\/en\/docs\/analytics\/implementation\/aep-edge\/hit-types\" target=\"_blank\" rel=\"noreferrer noopener\"> <\/a><a href=\"https:\/\/experienceleague.adobe.com\/en\/docs\/analytics\/implementation\/aep-edge\/overview#:~:text=and%20link%20events%3A-,XDM%20payload%20contains,-%E2%80%A6\" target=\"_blank\" rel=\"noreferrer noopener\">page name<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/fillingIn.png\"><img loading=\"lazy\" decoding=\"async\" width=\"782\" height=\"440\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/fillingIn.png\" alt=\"\" class=\"wp-image-1173\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/fillingIn.png 782w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/fillingIn-300x169.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/fillingIn-768x432.png 768w\" sizes=\"(max-width: 782px) 100vw, 782px\" \/><\/a><\/figure>\n\n\n\n<p>Then I\u2019d create my situation-specific rules (my \u201csandwich fillings&#8221;)- things that should only fire on certain pages or certain user actions. For instance, I might have a rule specific that fires on page load, only when my page type is \u201dSearch Results\u201d:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sandwichFillingRule.png\"><img loading=\"lazy\" decoding=\"async\" width=\"778\" height=\"641\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sandwichFillingRule.png\" alt=\"\" class=\"wp-image-1174\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sandwichFillingRule.png 778w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sandwichFillingRule-300x247.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sandwichFillingRule-768x633.png 768w\" sizes=\"(max-width: 778px) 100vw, 778px\" \/><\/a><\/figure>\n\n\n\n<p>Then in my \u201cupdate variables\u201d action, I would set the fields for Search Results Term, Number of Search Results, and whatever metric I want to increment to indicate the user has made a search query:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/searchFilling.png\"><img loading=\"lazy\" decoding=\"async\" width=\"796\" height=\"307\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/searchFilling.png\" alt=\"\" class=\"wp-image-1175\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/searchFilling.png 796w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/searchFilling-300x116.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/searchFilling-768x296.png 768w\" sizes=\"(max-width: 796px) 100vw, 796px\" \/><\/a><\/figure>\n\n\n\n<p>Note, when I increment a metric, I should use the number, without quotation marks- it needs to be an integer, not a string. If the data is being fed only into Analytics then it doesn\u2019t matter as much (it seems to handle strings and integers the same), but if the data is going into CJA, this will make it so much easier to turn it into a metric.<\/p>\n\n\n\n<p>Finally, we need to actually fire events off to Adobe\u2019s Edge. For page views, this is where the top slice of bread comes in: a rule, with order #100, with a webSDK \u201cSend Event\u201d action:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sendEvent.png\"><img loading=\"lazy\" decoding=\"async\" width=\"840\" height=\"487\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sendEvent.png\" alt=\"\" class=\"wp-image-1176\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sendEvent.png 840w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sendEvent-300x174.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/sendEvent-768x445.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/a><\/figure>\n\n\n\n<p>For non-page-views, I may just add that event to the existing \u201cfilling\u201d rule. This lets me specify an event type that suits that user action. OR, I may create a different \u201ctop slice of bread\u201d, if I have many rules all tracking something similar and I tire of adding a \u201cSend Event\u201d action to every single one of them. (Again, <a href=\"https:\/\/www.digitaldatatactics.com\/index.php\/2024\/02\/09\/the-adobe-launch-rule-sandwich\/#topSlice\" target=\"_blank\" rel=\"noreferrer noopener\">all of this is detailed in the original blog post<\/a>&#8211; just swap \u201cSet Variables\u201d for \u201cUpdate Variable\u201d, and \u201cSend Beacon\u201d for \u201cSend Event\u201d.)<\/p>\n\n\n\n<p>The final result should be an event payload that includes fields from your global rule and any rules where you updated your variable.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Gotchas<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"clearVars\">Clear variables<\/h4>\n\n\n\n<p>In the appMeasurement\/Adobe Analytics world, we had issues with variable persistence and sometimes had to clear out our variables, and the webSDK is no different. If, for example, when my page loads, I \u201cupdate my variable\u201d to set my Search Results metric to &#8220;1\u201d and fire an event, but then the user selects a search filter and I want to update the variable and fire an event again\u2026 that Search Results metric will still be \u201c1\u201d in my XDM variable. My \u201csearch filter\u201d event payload will include my search results event, as well as any event I set earlier on that page, potentially duplicating metrics.<\/p>\n\n\n\n<p>Fortunately, the \u201cUpdate Variable\u201d allows you to clear out previously-set fields. You can do this on a field-by-field basis, but with the Rule Sandwich setup, I find it easiest to just do it on my \u201cbottom slice\u201d global rule- select your top-level xdm object and check \u201cClear Existing Value\u201d.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearFullObject.png\"><img loading=\"lazy\" decoding=\"async\" width=\"930\" height=\"416\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearFullObject.png\" alt=\"\" class=\"wp-image-1186\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearFullObject.png 930w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearFullObject-300x134.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearFullObject-768x344.png 768w\" sizes=\"(max-width: 930px) 100vw, 930px\" \/><\/a><\/figure>\n\n\n\n<p><em>(10 points if you spot the typo in the interface)<\/em><\/p>\n\n\n\n<p>Since you\u2019re about to re-set all your important global variables, you don\u2019t have to worry about erasing anything you wanted to hang around. If you are concerned about clearing something important, you can focus on clearing out the fields your metrics are based on, since those tend to be the ones we don\u2019t want hanging around. For example, I can easily clear out most of my Adobe Analytics events by just focusing on the \u201cevent1to100\u201d objects:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearEvents.png\"><img loading=\"lazy\" decoding=\"async\" width=\"930\" height=\"457\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearEvents.png\" alt=\"\" class=\"wp-image-1178\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearEvents.png 930w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearEvents-300x147.png 300w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/clearEvents-768x377.png 768w\" sizes=\"(max-width: 930px) 100vw, 930px\" \/><\/a><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"propertycopy\">Copying between properties<\/h4>\n\n\n\n<p>We came across an interesting bug when using \u201cUpdate Variable\u201d when we tried to copy the whole set up from one Launch Property to another. We copied the XDM Variable Data Element and every rule that used it. Both properties followed the same schema and used the same datastreams, so it felt like a simple lift-and-shift. In the interface, everything looked great\u2026 but nothing worked. I was just helping out (it wasn\u2019t my client) so I didn\u2019t have access to the Launch properties in question, so I had to resort to troubleshooting in the code\u2026 which ended up being a good thing, because only there could I have seen the \u201cUpdate Variable\u201d action doesn\u2019t reference the XDM Variable Data Element <em>name<\/em>, but rather, some internal ID, and that internal ID seemed to be copied from the original property.<\/p>\n\n\n\n<p>The data element itself had one ID:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarCode.png\"><img loading=\"lazy\" decoding=\"async\" width=\"501\" height=\"90\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarCode.png\" alt=\"\" class=\"wp-image-1179\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarCode.png 501w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarCode-300x54.png 300w\" sizes=\"(max-width: 501px) 100vw, 501px\" \/><\/a><\/figure>\n\n\n\n<p>But the code for the Rule with the \u201cUpdate Variables\u201d action seemed to be referencing something else altogether:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarNewCode.png\"><img loading=\"lazy\" decoding=\"async\" width=\"469\" height=\"388\" src=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarNewCode.png\" alt=\"\" class=\"wp-image-1180\" srcset=\"https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarNewCode.png 469w, https:\/\/www.digitaldatatactics.com\/wp\/wp-content\/uploads\/2025\/04\/webSDKvarNewCode-300x248.png 300w\" sizes=\"(max-width: 469px) 100vw, 469px\" \/><\/a><\/figure>\n\n\n\n<p>Whereas the original property (which still worked) had the same ID (the one ending \u201c4d3d\u201d) in both of those spots. So our <em>new<\/em> property\u2019s Update Variables actions were seemingly trying to reference the ID of the XDM Variable Data Element from our <em>original<\/em> property.<\/p>\n\n\n\n<p>In my testing on my own properties, I could see that it should be as simple as giving your new property\u2019s XDM Variable Data Element a slightly different name (in my experience, it only worked if the data element had a new name, otherwise it kept trying to reference the old ID) and going through each Update Variable Action and changing its variable to your new property\u2019s newly-renamed Data Element. In my testing, at least, I did NOT lose the mappings I had worked so hard on when I changed my variable (hooray). It is annoying to have to do this in all your Update Variable actions, but better than starting from scratch. Make sure you also update the variable reference in your \u201cSend Event\u201d actions.<\/p>\n\n\n\n<p>(Since I wasn\u2019t technically on the account in question, I didn\u2019t submit this as a bug to client care and I don\u2019t know if anyone else has, but someone probably should.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What works for you?<\/h3>\n\n\n\n<p>This is a method that has worked well for me, but (as any honest agency\/consultant should tell you at this point)\u2026 we\u2019re all still figuring this webSDK\/XDM\/CJA stuff out as we go. Unlike appMeasurement (and H code before it), I don\u2019t have nearly 20 years of experience to tell you all the gotchas and to be able to say which methods will withstand the test of time. I have been on alphas\/betas\/POCs for the webSDK since 2019, but I only have a few XDM projects where I have been able to look back a year or two later and say \u201cthat worked well\u201d or \u201cI wish I had done something different\u201d.<\/p>\n\n\n\n<p>I\u2019m grateful for consultants from other agencies (Adswerve and Slalom, in particular) not to mention MANY individual practitioners that have helped me puzzle some of this out. We all benefit from knowledge-sharing at this point, and one of my favorite things about this industry is how much folks generally care more about learning and sharing than they care about \u201ccompetition\u201d.<\/p>\n\n\n\n<p>I\u2019ll update this post if I figure anything out that\u2019s relevant, and hope folks will reach out to me if they discover something that works better, or some other gotcha folks should be aware of.<\/p>\n\n\n\n<p><em>*Still not calling it \u201cAdobe Experience Platform Data Collection Tags\u201d<\/em><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Migrating to the webSDK doesn\u2019t mean giving up on implementation methods that scale. Adobe provides a little-known \u201cUpdate Variable\u201d mechanism in Launch that allows you to build a scaleable, maintainable implementation with minimal redundancy. <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76,44],"tags":[57,74,75,8,30,45,42],"_links":{"self":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts\/1167"}],"collection":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/comments?post=1167"}],"version-history":[{"count":8,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts\/1167\/revisions"}],"predecessor-version":[{"id":1208,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/posts\/1167\/revisions\/1208"}],"wp:attachment":[{"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/media?parent=1167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/categories?post=1167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.digitaldatatactics.com\/index.php\/wp-json\/wp\/v2\/tags?post=1167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}