my topic is about the relatively new product "predictive web" there are multiple contradictory facts delivered by salesforce which makes implementation hard or nearly impossible. I will quote multiple statements by salesforce documentation and their implementation instructions.

The main topic is the definition of the product catalog and the tracking code to match this catalog.

So let's begin.

Extract from your documentation:

SkuID Attribute Description: Unique identifier for each product, specific to the customer. This must match the product sku on the website and be passed via Collect Code.

ProductCode Attribute Description:Used to identify a group of related products. For example, a piece of apparel will appear in the catalog multiple times with a unique SkuID for each size the product is available in, all of these size variations will be sent with the same ProductCode. The ProductCode value cannot contain spaces or special characters.

Extract from the implementation instruction inside predicitive web:

Extract from your Tracking Code implementation on the install instructions in the Marketing Cloud: <script> _etmc.push(["setOrgId", "MID-Number"]); _etmc.push(["trackPageView",{ "item" : "INSERT_PRODUCT_CODE" }]); </script>

Replace 'INSERT_PRODUCT_CODE' with dynamic code to pull the UNIQUE IDENTIFIER for the item being viewed. If you have connected or uploaded a catalog file, the value sent in place of 'INSERT_PRODUCT_CODE' must match the value mapped to your ProductCode catalog field.

To make it even clearer i provide you with a few lines of the sample_catalog.psv delivered by salesforce:

12345|XCode12340|Brand X Whiz 9000|Electronics|http://www.companyx.com/products/12345|http://www.companyx.com/images/12345.jpg|80.89|72.8|Brand X|Blue~Red|4.12|1|8/27/2012|Technology~Music
12346|XCode12340|Brand X Whiz 9001|Electronics|http://www.companyx.com/products/12346|http://www.companyx.com/images/12346.jpg|94.57|85.11|Brand X|Blue~Red|4.12|1|8/28/2012|Technology~Music
12347|XCode12340|Brand X Whiz 9002|Electronics|http://www.companyx.com/products/12347|http://www.companyx.com/images/12347.jpg|22.08||Brand X|Blue~Red|4.12|1|8/29/2012|Technology~Music
12357|XCode12350|Brand X Whiz 9012|Headphones|http://www.companyx.com/products/12357|http://www.companyx.com/images/12357.jpg|54.92|49.43|Brand X|Blue|4.12|3|9/8/2012|Technology~Music
12349|XCode12340|Brand X Whiz 9004|Electronics|http://www.companyx.com/products/12349|http://www.companyx.com/images/12349.jpg|7.73||Brand X|Blue|4.12|1|8/31/2012|Technology~Music
12350|XCode12350|Brand X Whiz 9005|Electronics|http://www.companyx.com/products/12350|http://www.companyx.com/images/12350.jpg|94.29|84.86|Brand X|Blue|4.12|1|9/1/2012|Technology~Music

A summary: Salesforce told contradictory facts by now.

Catalog Documentary says ProductCode is not unique, Catalog install instruction says that i have to pass a unique identifier which is matched on the productcode field ==> productcode has to be unique. The sample_catalog shows that the productcode should not be unique.

What is the truth here?

To continue with our problem, what we have tried to do:

  1. Catalog: ProductCode not unique, Tracking Code: Sends non unique Product Code to Salesforce, Result: Error "An item not in the catalog was viewed".
  2. Catalog: ProductCode can be unique for items with only one article, Tracking Code: Sends the value of this specific product, Result: No error by Salesforce (seems to work). But how would you group multiple Articles under a productcode? This wouldn't be possible if ProductCode is unique.
  3. Catalog: ProductCode not unique, Tracking Code: Sends unique value which is stored under SkuID in Product Catalog, Result: "An item not in the catalog was viewed". With this test we tried if Salesforce might match to SkuID and not ProductCode field. But it seems that the data of the tracking code "item" is matched against ProductCode, where this value is obviously not stored.
  4. Now i tried to switch the values of productcode and skuid. So the field ProductCode would contain the articlenumber value and the field SkuID would be the productcode. Result: This is simply not possible because of your mapping functionality. Since i have to define the unique field when i start to upload the catalog, this field won't show up in the mapping view. Therefore it is impossible to pass those values to product code unless i would double that field [which would be completly missleading].
  5. Each Product has an own line in the product catalog, where the sku is artificial, since it is no article. Each article has a productcode which is artificial and doesn't relate to the product. But the productcode field has a unique value now. Result: Everything works, but i think it is not the way it should be.

The tracking code is implemented on product pages (not article pages) and looks like this:

<script type="text/javascript" src="//MID-Value.collect.igodigital.com/collect.js">

_etmc.push(["setOrgId", "MID-Value"]);
_etmc.push(["trackPageView",{ "item" : "P11111111111" }]);

When we uploaded the catalog we tried multiple things to make sure that there is not a mistake:

  1. First of all we tested different suffixes .pdv .psv .csv. ==> No Success
  2. We renamed the header fields of the catalog to ensure we didnt hit a keyword ==> No Success
  3. We doublechecked over special characters and encoding and all this stuff. ==> No Success

What can i do now? All options we did are either not working, really early work arounds or not usable for real scenarios. Is there some option i did not try? Is there anything i need to pay more attention on?

Additional Questions:

  1. How is it possible to track articles?
  2. Which json-"keyword" of trackPageView matches against the SkuID field of the product catalog?
  3. When you want to do recommendations based on the context of the current website the code looks like the one shown below. Does item relate to productcode or the SkuID field?
src="https://MID-VALUE.recs.igodigital.com/a/v2/MID-VALUE/product/recommend.json?item=sku" type="text/javascript">

Thank you for reading. I hope someone can tell a solution or some detailed insight in this.

1 Answer 1


Here is a list of attributes for you. The specific one you're looking for may be "ContentID" or "SkuID" depending on the catalogue type. In my implementation of a content catalogue, there are a few steps in this order:

Step 1: Set and collect the data

<script src="//{MID}.collect.igodigital.com/collect.js"></script>
    _etmc.push(["setOrgId", "{MID}"]);//Tracks to this MID
    _etmc.push(["setUserInfo", { "email": "{USER_EMAIL_ADDRESS}" } ]);//Tracks to this user
    _etmc.push(["trackPageView", { "item": "{CONTENT_ID}" }]);//Tracks page view of this product, matches the "ContentID" for content or "SkuID" for products

Step 2: Dynamically stream the item's update to your catalogue (as opposed to a batch upload of a pipe delimited file)

    _etmc.push(["updateItem", {
        "item_type": "content",// or "product" for a product catalogue
        "item": "{CONTENT_ID}",//Matches the "ContentID" for content or "SkuID" for products
        "url": "{ABSOLUTE_URL}",
        "available": "{AVAILABILITY}",// Accepts "Y" or "N"
        "name": "{CONTENT_NAME}",
        "image_link": "{IMAGE_ABSOLUTE_URL}",
        "author": "{AUTHOR}",
        "release_date": "{PUBLISHED DATE}",//Should be in YYYY-MM-DD format
        "abstract": "{DESCRIPTION}",

If you're wondering where I got these keywords from, you can find them in your specific catalogue's implementation by going to Admin > Implementation when viewing the Web Recommendations dashboard.

When updating items in the content catalogue via a batch file, I'm using the list of attributes as my column headers, like this:


The batch file is pipe-delimited with each item on it's own line and has the "psv" file extension, much like your example. Though make sure if a field is empty, there is still a pipe for it, like how I've omitted the "author" from this:

9999|https://example.com/9999/|Y|Foo|https://example.com/media/9999.jpg||2019-11-25|Lorem ipsum dolor sit amet.

I actually have both the batch file updating the catalogue every 24 hours as well as the dynamic streaming updates.

When it comes to scenarios, here's some documentation on which attributes are needed to drive them.

Step 3: Recommend personalized content/products to the user

<script src="https://{MID}.recs.igodigital.com/a/v2/{MID}/product/recommend.js?item={CONTENT_ID}&email={USER_EMAIL_ADDRESS}"></script>

The "item" parameter in recommend.js or recommend.json refers to the "ContentID" (in a content catalogue) or "SkuID" (in a product catalogue), the same that gets passed as "item" in the "updateItem" push. The "email" parameter refers to the "email" attribute sent in the "setUserInfo" push. Keep in mind that the email address does not have to be a valid email address. If you want to track/personalize for anonymous users, you can generate a random unique ID or GUID and pass that along instead.

So putting it all together, the final snippet might look something like this:

<script src="//1234567890.collect.igodigital.com/collect.js"></script>
    _etmc.push(["setOrgId", "1234567890"]);//Tracks to this MID
    _etmc.push(["setUserInfo", { "email": "[email protected]" } ]);//Tracks to this user
    _etmc.push(["trackPageView", { "item": "9999" }]);//Tracks page view of this product, matches the "SkuID" in the product catalogue
    _etmc.push(["updateItem", {
        "item_type": "product",
        "item": "9999",//Matches "SkuID" in the product catalogue
        "url": "https://example.com/products/9999/",
        "available": "Y",// Accepts "Y" or "N"
        "name": "Foo",
        "image_link": "https://example.com/media/9999.jpg",
        "author": "Bar",
        "release_date": "2019-11-25",//Should be in YYYY-MM-DD format
        "abstract": "Lorem ipsum dolor sit amet.",
<script src="https://1234567890.recs.igodigital.com/a/v2/1234567890/product/recommend.js?item=9999&[email protected]"></script>

Hope this helps!

  • Hi Tessa, in short: this does not help but i greatly appreciate your trial to help. Just ask yourself the question: How do you track product and artcile views / purchases (at the same time) without doing a workaround (like each article has its own productcode) with the same code? You can not group articles under a product because there is no hierarchy involved in salesforce algorithms. I had a discussion with the lead of the marketing cloud Rick Thomas, aswell as with many community member like Evangeline Burris Cook - nobody was able to help and its a clear contradiction. Nov 25, 2019 at 20:04
  • Are you trying to create a hierarchical relationship between products and articles? I'm sure we can come up with a smart solution with using custom tags if that's the case. Are you using a CMS or something to store your values?
    – AuRise
    Nov 25, 2019 at 20:51
  • Articles or called SKUs and products are structured in hierarchy by default. sku vs product Nov 25, 2019 at 21:15
  • Oh, I thought when you said articles, you were referring to an item in a content catalogue (like a blog article), which is different than a product in a product catalogue. I believe you're using articles to refer to their "product code" in Salesforce terminology? If you're tracking items at the Sku level, you can't track them at the product code level. Despite their documentation saying that the SkuID is not required and that the ProductCode is, I'd still write my code to always submit a SkuID to be consistent. If there is no variation, it'd be the same as the ProductCode.
    – AuRise
    Nov 25, 2019 at 21:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .