How to Unify Product and CMS Records
This steps shown in this tutorial are meant for technical resources.
In this tutorial, we have content records in Storyblok
that has a field (called featuredProduct
) that contains a product SKU. We want to use that SKU to retrieve the product record from our product catalog in commercetools
and then use that product record to render a product detail page. We will use the DX Engine to unify the product and content records.
- Setup a productSku Context Field
- Setup a Connection to Storyblok (using a Secret that points to Conscia's Storyblok sandbox)
- Setup a Component to retrieve the Storyblok content record
- Setup a Connection to commercetools (using a Secret that points to Conscia's commercetools sandbox)
- Setup a Component to retrieve the commercetools product record
- Setup a Component to merge the output of the Storyblok and commercetools Components
Your sandbox should have already been seeded with the following secrets:
Secret Code | Name |
---|---|
conscia-sandbox-storyblok-delivery-token | Storyblok Delivery Token for Conscia Sandbox |
conscia-sandbox-storyblok-management-token | Storyblok Management Token for Conscia Sandbox |
conscia-sandbox-commercetools-client-id | Commercetools Client ID for Conscia Sandbox |
conscia-sandbox-commercetools-client-secret | Commercetools Client Secret for Conscia Sandbox |
Setup "productSku" Context Field
In this section we will setup a Context Field called productSku
that will be used to hold the productSku that we will pass to the DX Engine.
- Navigate to the
Settings --> Context Fields
page in the DX Engine UI. - Click the
+
button to create a new Context Field. - Fill in the Context Field form as follows:
Property | Value |
---|---|
Context Field Name | productSku |
Display Name | Product SKU |
Data Type | String |
Setup a Webservice Connection to Storyblok
In this section we will setup a Connection to Storyblok that will be used to retrieve the content record that contains the product SKU. We will use the Universal API Connector.
- Navigate to the
Settings --> Connections
page in the DX Engine UI. - Click the
+
button to create a new Connection. - Fill in the Connection form as follows:
Property | Get value from | Value |
---|---|---|
Connection Code | storyblok-webservice-connection | |
Connection Name | Storyblok Webserbice Connection | |
Connector | Universal API Connector | |
Base URL | https://api-us.storyblok.com/v2/cdn/stories | |
Method | GET | |
Query Parameters #1, Parameter | token | |
Query Parameters #1, Value | Secret | Storyblok Token for Conscia Sandbox |
Setup a Component to retrieve the Storyblok content record via produtSku
- Navigate to
Manage Experiences --> Experience Components
- Click the
+
button to create a new Component. - Fill in the Component form as follows:
Property | Value |
---|---|
Component Code | storyblok-product-record |
Component Name | Product Record from Storyblok |
Component Type | Conscia - Universal API Connector |
Click the
Submit
buttonRight-click the
Storyblok Product Record
Component and clickUpdate
.Fill in the form as follows:
Property | Get value from | Value |
---|---|---|
Connection | Storyblok Webservice Connection | |
Method | GET | |
Query Parameters #1, Parameter | filter_query[featuredProduct][like] | |
Query Parameters #1, Value | Context Field | Product SKU |
- Click the
Submit
button
Query the Storyblok Product Record Component
Conscia's Storyblok sandbox has a content record for the product with SKU hobbit
. We can query the Storyblok Product Record
Component to retrieve the content record for the product with SKU hobbit
as follows:
POST {{dxEngineUrl}}/experience/components/_query
Content-Type: application/json
Authorization: Bearer {{token}}
X-Customer-Code: {{customerCode}}
{
"componentCodes": ["storyblok-product-record"],
"context": {
"productSku": "hobbit"
}
}
The response property, components.storyblok-product-record.response.stories[0].content
, will contain the content record for the product with SKU hobbit
.
Setup a Connection to Commercetools
In this section we will setup a Connection to Commercetools that will be used to retrieve the product record for the specified product SKU. We will use the Commercetools Connector.
- Navigate to the
Settings --> Connections
page in the DX Engine UI. - Click the
+
button to create a new Connection. - Fill in the Connection form as follows:
Property | Get value from | Value |
---|---|---|
Connection Code | commercetools-product-connection | |
Connection Name | Conscia Sandbox Connection for Commercetools | |
Connector | Commercetools | |
Project Key | omni-channel-experience | |
Hosting region | North America (Goolge Cloud, Iowa) | |
Client Id | Secret | conscia-sandbox-commercetools-client-id |
Client Secret | Secret | conscia-sandbox-commercetools-client-secret |
Setup a Component to retrieve the commercetools product record
- Navigate to
Manage Experiences --> Experience Components
- Click the
+
button to create a new Component. - Fill in the Component form as follows:
Property | Get value from | Value |
---|---|---|
Component Code | commercetools-product-record | |
Component Name | Commercetools Product Record | |
Component Type | Commercetools - Static Product List |
- Click the
Submit
button - Right-click the
Commercetools Product Record
Component and clickUpdate
. - Fill in the form as follows:
Property | Get value from | Value |
---|---|---|
Connection | Conscia Sandbox Connection for Commercetools | |
Enter the IETF language code | en-uS | |
Product Keys | JS Expression | [contextField('productSku')] |
We used the a JS Expresion to provide the Product Keys property with the value of the productSku
Context Field within an array (since the Commercetools Connector expects an array of product SKUs).
- Click the
Submit
button
Query the Commercetools Product Record Component
Conscia's Commercetools sandbox has a product record with the SKU, hobbit
. We can query the Commercetools Product Record
Component to retrieve the product record for the product with SKU hobbit
as follows:
POST {{dxEngineUrl}}/experience/components/_query
Content-Type: application/json
Authorization: Bearer {{token}}
X-Customer-Code: {{customerCode}}
{
"componentCodes": ["commercetools-product-record"],
"context": {
"productSku": "hobbit"
}
}
Merging the Storyblok and Commercetools Records
To fetch both records in a single request, we specify both component codes in the request as follows:
POST {{dxEngineUrl}}/experience/components/_query
Content-Type: application/json
Authorization: Bearer {{token}}
X-Customer-Code: {{customerCode}}
{
"componentCodes": ["commercetools-product-record", "storyblok-product-record"],
"context": {
"productSku": "hobbit"
}
}
The component response looks like this:
{
"storyblok-product-record": {
"@extras": {
"rule": {
"metadata": [],
"attributes": {}
}
},
"status": "VALID",
"response": {
"stories": [
{
"name": "Tolkien ",
"created_at": "2023-06-29T15:59:37.120Z",
"published_at": "2023-06-29T16:03:12.802Z",
"id": 174100,
"uuid": "ff638562-a2a5-4f5f-b1ea-28930582fc3f",
"content": {
"url": "",
"_uid": "d9673bfc-b842-4ea0-8a73-58fcd254ff68",
"body": "https://chat.openai.com",
"image": {
"id": null,
"alt": null,
"name": "",
"focus": null,
"title": null,
"source": null,
"filename": "",
"copyright": null,
"fieldtype": "asset",
"meta_data": {}
},
"title": "J.R.R. Tolkien: A Literary Legend and Father of Modern Fantasy",
"component": "Articles",
"description": "Explore the captivating life and extraordinary imagination of J.R.R. Tolkien, the brilliant author behind the beloved Middle-earth tales and the creator of a genre that continues to inspire generations of readers and writers alike.",
"featuredProduct": "hobbit"
},
"slug": "tolkien",
"full_slug": "tolkien",
"sort_by_date": null,
"position": -50,
"tag_list": [],
"is_startpage": false,
"parent_id": null,
"meta_data": null,
"group_id": "795c0364-edca-4792-bd34-ada6a85961a5",
"first_published_at": "2023-06-29T16:03:12.802Z",
"release_id": null,
"lang": "default",
"path": null,
"alternates": [],
"default_full_slug": null,
"translated_slugs": null
}
],
"cv": 1688054630,
"rels": [],
"links": []
}
},
"commercetools-product-record": {
"@extras": {
"rule": {
"metadata": [],
"attributes": {}
}
},
"status": "VALID",
"response": [
{
"id": "13ea40eb-1b9a-438d-8824-6347f96862e0",
"version": 3,
"productType": {
"typeId": "product-type",
"id": "6eb9f35c-d8ed-4120-8c10-49de4900a056"
},
"name": {
"en-US": "The Hobbit"
},
"description": {
"en-US": "Best selling fantasy fiction"
},
"categories": [],
"categoryOrderHints": {},
"slug": {
"en-US": "the-hobbit"
},
"metaTitle": {
"de-DE": "",
"en-US": ""
},
"metaDescription": {
"de-DE": "",
"en-US": ""
},
"variants": [],
"masterVariant": {
"attributes": [],
"assets": [],
"images": [],
"prices": [],
"key": "123",
"sku": "123",
"id": 1
},
"searchKeywords": {},
"hasStagedChanges": false,
"published": true,
"key": "hobbit",
"createdAt": "2022-09-29T23:34:54.800Z",
"lastModifiedAt": "2022-09-29T23:44:57.762Z"
}
]
}
}
Setup a Component to merge the Storyblok and Commercetools Records
- Navigate to
Manage Experiences --> Experience Components
- Click the
+
button to create a new Component. - Fill in the Component form as follows:
Property | Get value from | Value |
---|---|---|
Component Code | full-product-record | |
Component Name | Full Product Record from Storyblok and Commercetools | |
Component Type | Conscia - Object Mapper |
- Click the
Submit
button - Right-click the
Full Product Record from Storyblok and Commercetools
Component and clickUpdate
. - Create two Object Maps by clicking
+ Add another item
twice.
Editing the first Object Map
- Fill in the form as follows:
Property | Get value from | Value |
---|---|---|
Source data | Component Response | Storyblok Product Record |
Expression Type | jmespath |
- Edit
Schema
by clickingEdit Object
- Add expressions,
contentTitle
andcontentDescription
underObject Root
Editing the second Object Map
- Fill in the form as follows:
Property | Get value from | Value |
---|---|---|
Source data | Component Response | Commercetools Product Record |
Expression Type | jmespath |
- Edit
Schema
by clickingEdit Object
- Add expressions,
productName
andproductSlug
underObject Root
The final form should look like this:
- Click the
Submit
button
Query the Full Product Record
To fetch the merged records:
POST {{dxEngineUrl}}/experience/components/_query
Content-Type: application/json
Authorization: Bearer {{token}}
X-Customer-Code: {{customerCode}}
{
"componentCodes": ["full-product-record"],
"context": {
"productSku": "hobbit"
}
}
The response will look like this:
{
"contentTitle": "J.R.R. Tolkien: A Literary Legend and Father of Modern Fantasy",
"contentDescription": "Explore the captivating life and extraordinary imagination of J.R.R. Tolkien, the brilliant author behind the beloved Middle-earth tales and the creator of a genre that continues to inspire generations of readers and writers alike.",
"productName": "The Hobbit",
"productSlug": "the-hobbit"
}
Since the full-product-record
Component references both the Storyblok and Commercetools Components, DX Engine knows to run them both first (and in parallel) before running the full-product-record
Component.