Skip to main content
Use server-side personalization

Access additional personalization options.

Updated over a month ago

The simplest way to personalize your website is by using the standard Fresh Relevance Site Editor. This allows you to change the content which is seen, and where, using a WYSIWYG editor. Once you've published your changes, the Fresh Relevance loads your content when visitors come to your website. This is called client-side personalization, because the content is displayed using client-side JavaScript.

Some users prefer or need to use an approach where the personalization is done on the server, and the personalized content is sent as part of the overall page HTML. This is called server-side personalization, because the content is personalized on the server.


When to consider server-side personalization

  • You're calling other APIs to build the page, and are using those results in the personalization.

  • You're making changes to the structure of the page, for example, changing the order of several sections.

  • You want to avoid any possibility of flicker. This can be a particular issue if parts of the page are being conditionally added or omitted.

  • You want to maximize the indexing by search engines of your long-tail products.
    Learn more in The impact of personalization on SEO.

  • You want to render a personalized single page app (SPA).

  • You are building a mobile app.
    Learn more in Mobile and app API.

Benefits and advantages of server-side personalization

  • No content load flicker - also called Cumulative Layout Shift, or CLS.

  • More consistent content loading.

  • Content is indexed more often by Google.

  • Unlikely to be affected by Script or Popup blockers.

  • More developer control.

Disadvantages

  • Possibly slower initial page load.

  • Less marketer control - Developer and IT support are required to implement changes to which Slots appear where.

  • Harder to do testing and to change where personalized elements are located on the page.

Some organizations use a hybrid approach: they use client-side personalization for areas of the website which are rapidly evolving, because it's much easier and quicker to make changes and test new content. Then, more mature areas are moved to a server-side approach when the page structure has become more settled.

Other organizations use client-side personalization for tasks such as swapping banners, but use a server-side approach to add or remove structural parts of the page, such as a dashboard.

Whether you use server-side or client-side personalization, remember that Fresh Relevance marketing rules allow you to change the content that is shown without changing the Slot itself. So, even with a server-side personalization approach, there is still a lot of flexibility for the business users of the platform to change the content which is shown to each individual.


Record events and activity from your server or app

The Mobile and App API allows your mobile apps, PWAs, services and other systems to pass data to Fresh Relevance, as well as use the platform’s technology to drive personalization in your apps, web pages and other channels.

The standard configuration of Fresh Relevance captures data about shoppers’ behavior using JavaScript on every webpage of a website. This is called client-side data collection. This JavaScript sends data to the Fresh Relevance server for each page visited. This is referred to as a beacon and includes a JSON structure containing the following types of data:

  • Product Details Page

    • Device ID (Cookie)

    • Product information such as ID, name, image, URL, description, price

  • Product List Page

    • Device ID (Cookie)

    • Array of products and information such as ID, name, image, URL, description, price

  • Cart Page

    • Device ID (Cookie)

    • A list of all Products in the cart and information such as ID, name, image, URL, description, price, quantity

    • Cart level information such as cart price

  • Transaction Complete Page

    • Email address of visitor

    • Device ID (Cookie)

    • Email address

This is not an exhaustive list.

Additional custom data can be sent for both the person, for example a CRM ID, and for the product(s).

As an alternative, you can also collect data on your web server (server-side) and from your mobile apps.

Record data on your webserver using the API

Data capture for websites driven from your server is straightforward – your web server just needs to make an HTTP POST for each page that is viewed.

For example, your website should post a beacon of type 1 (PRODUCT_BROWSE) for every product page that’s visited. With this beacon, you should supply details of the product(s) viewed and the cookie ID of the visitor.

Learn more in Mobile and app API. See also the Postman documentation for Mobile Data Collection.


Fetching personalized HTML

Your server or app can easily retrieve content from Fresh Relevance for use on your site by making an HTTP GET request for each piece of content that’s viewed. The content can be retrieved either in JSON format or in HTML format. In JSON format, information is returned such as the list of items in a recommendation block. You could use these to drive other types of content on the webpage.

To personalize a web page or email, Fresh Relevance Slots are used. Each Slot is a location for content and can be used on either a web page or an email. The content - called a SmartBlock - which is actually displayed by the Slot can be changed flexibly and at any time using content rules, configured using the Fresh Relevance UI. The same approach works for mobile app personalization as well.

Your server can make an HTTP GET request to the Fresh Relevance server and retrieve back either JSON or HTML representing the Slot. This can then be rendered into the mobile app or web page.

Here’s an example of a URL which returns a block of HTML for the Slot in response to a GET request:

​​https://c[account partition number].dycdn.net/[account ID]/s/[Slot Id]/?k=[API token]&format=full

This endpoint also supports personalization by including an identifier for the shopper in the query string parameter.

The following parameters are supported:

Parameter

Notes

Example URL

e

The shopper's email address.

https://c[account partition number].dycdn.net/[account ID]/s/[Slot ID]/?k=[API token]&e=test@example.com&format=full

d

An identifier for a device the shopper used to visit your website.

The device ID is a cookie value that is generated by our script on your website.

This is stored in the tms_VisitorID cookie. This is a first-party cookie, so is available in the Cookie HTTP header on requests to your server.

https://c[account partition number].dycdn.net/[account ID]/s/[Slot ID]/?k=[API token]&d=[device ID]&format=full

cid

The shopper's customer ID. This only works if this value is captured our system.

Learn more in Import person data.

https://c[account partition number].dycdn.net/[account ID]/s/[Slot ID]/?k=[API token]&cid=[customer ID]&format=full

If you're using filters to return relevant content based on the specific site then you may also need to pass through additional parameters, such as the product ID (prid), site brand (sbr) or currency (curr).

For example:

https://c[account partition number].dycdn.net/[account ID]/s/[Slot ID]/?k=[API token]&d=[Device ID]&prid=1234&sbr=uk&curr=GBP

To find the specific URL for a Slot stored in your account:

  1. Go to Content > Slots.

  2. Select the Web Personalization tab.

  3. Select the Slot you want, then select the Use icon.

  4. The URL to request that slot is shown under Feed URL.

Learn more in Mobile and app API. See also the Postman documentation for Mobile Personalization.

Slot URL parameters

The above URLs can optionally take the following parameters:

Parameter

Notes

format=html

Returns the SmartBlock selected by the Slot formatted as HTML.

Normally use format=full instead.

format=blockimage

Returns the SmartBlock selected by the Slot formatted as an image.

format=dynamichtml

Returns open-time HTML.

Not needed for server-side personalization.

format=full

Returns everything as a JSON container, with HTML inside, plus metadata.

format=compact

Returns everything as a JSON container, no HTML, matching items inside items, plus metadata.
For Recommendations, to return product IDs without the accompanying HTML.

format=appjson

Returns everything as a JSON container, with HTML inside, matching items inside items, plus metadata.

If you want to programmatically list or update Slots or SmartBlocks, see the Integration API article.


SmartBlock options

Some SmartBlock options require additional explanation and clarification when used in conjunction with server-side personalization.

Freeze open-time content

This SmartBlock option allows the set of products chosen for a recommendation SmartBlock to be frozen for a period of time. This means that if the shopper sees a particular recommendation block, or your app requests the SmartBlock, then comes back within that period of time and sees or requests the same recommendation block again, the same products are shown, in the same order.

The set of products is only frozen where the URL used for the recommendation SmartBlock is exactly the same. Any change to the URL, including the format, results in a different set of products being shown when the SmartBlock is revisited.

Connection pooling

Within the server application from which you're requesting the personalized content, you want to make sure that the requests are as efficient as possible. One aspect of this is to make sure you're using connection pooling. This reduces the time required to make repeated connections to the Fresh Relevance server.

The implementation details of this depend on the language and library that you’re using, but as an example in Python, you might use the connection pooling implemented by urllib3.


Advanced: Building your own HTML

Add link tracking to enable reporting

If you’re building your own HTML from the data returned by the appjson, compact, and full request types, for example, from the product IDs to recommend, then you need to make sure you add some tracking information so the click-throughs are tracked by Fresh Relevance

The necessary tracking parameters are in the meta JSON field from the response for appjson, compact, and full request types:

{"meta":
{
"tmsl":"my-slot-here",
"tmsb":"abc123",
"tmrl":"xyz123",
"tmcs":"yyy000",
"tmcv":0
}
}

URL parameters and their meaning:

  • tmsl - Slot ID

  • tmsb - SmartBlock ID

  • tmrl - Rule ID

  • tmcs - Layout ID

  • tmcv - Layout Version

An extra URL parameter is also needed for web:

  • tmty - Slot type (email or web)

You should then make a HTTP POST to the URL:

https://c[account partition number].dycdn.net/[account ID]/tc/?k=[API token]

with a body containing a JSON-encoded object:

{
"meta": { // Full "meta" object as received from the content response
"tmsl":"my-slot-here",
"tmsb":"abc123",
"tmrl":"xyz123",
"tmcs":"yyy000",
"tmcv":0,
"tmty": "w", // Defaults to w (web), can also use "e" (email)
},
"oid": "DtqoVDld2Xcj1sYBySy2xw==", // object ID of the item that was clicked (if present)
"vid": "a235235b", // vid (variant ID) value from the item that was clicked (if present)
"c": "abc123", // Cookie ID for the user that clicked
"target": "https://www.example.com/product1" // URL of the link (e.g. to the item clicked)
}

Click tracking client-side helper

If you are operating on the client-side, for example, with a PWA or SPA, then we have also provided a helper to allow you to submit the click tracking data. This requires you to have the Fresh Relevance script on your site. As with the manual option, you must pass the full meta object you receive in the personalization response to the function.

$TB.trackClick(meta, url, oid, vid)

The user's cookie ID is automatically included by the helper.

The oid must be the _id value of the item, not the product ID (prid) value. It should look similar to DtqoVDld2Xcj1sYBySy2xw==.

The vid (variant ID) value should be passed if present, otherwise omitted.


Advanced: Multi-Slot

The MultiSlot API is used for websites and apps doing large-scale personalization. It fetches several slots at once, which results in less round-trips to and from the server, and is therefore faster.

https://c[account partition number].dycdn.net/[account ID]/multislots/[slotid1],[slotid2],.../?k=[API token]

This endpoint also supports personalization by including the email of the shopper in the e query string parameter:

https://c[account partition number].dycdn.net/[account ID]/multislots/[slotid1],[slotid2]/?k=[API token]&e=test@example.com

By default the request returns a JSON list of objects that contain the HTML in the html field. The response can be formatted to return the HTML separated by a fixed string by setting the format to SFMC. The separator can be specified by the sfmc_separator parameter:

https://c[account partition number].dycdn.net/[account ID]/multislots/[slotid1],[slotid2]/?k=[API token]&format=sfmc&sfmc_separator=[slot end]

To limit how long to wait for the request use the response_timeout query string parameter. The value is the maximum number of seconds to wait for a response, for example, set to 25s to wait up to 25 seconds. If any of the content fails to load within this time the whole request returns an error.

https://c[account partition number].dycdn.net/[account ID]/multislots/[slotid1],[slotid2]/?k=[API token]&response_timeout=25

All other query string parameters are used when rendering the individual Slots and SmartBlocks.


Use Experiences with server-side personalization

Experiences let you control content across multiple channels such as web, email, and mobile app.

There are two ways to use experiences with your mobile apps:

  1. Use your own logic to determine which Slots to use in which parts of your app. If you’re doing this, then the best approach is to use an Is on experience X rule within the Slot rules for each Slot used by your mobile app.

    For example, you might use a rule Is on experience: VIP to select a recommendation block based on previous purchases, and another rule Is on experience: New Customer to select recommendations based on trending products.

  2. Using the Experiences API, you can use the configuration of your web pages in Site Editor to control which content appears in your app. This is a good approach if you have web pages which correspond directly onto pages in your app. Your app can get a list of the Slots which should appear on a specific page, and then request the content. You still need to use logic in your app to determine where in the app page the content is incorporated.

Use the Experiences API to retrieve a list of Slots used on a page

To make the API call, issue a GET against a URL like this:

https://c[account partition number].dycdn.net/[account ID]/campaigns/?k=[API token]&d=ptfbxnnebe&url=https%3A%2F%2Fwww.mysite.com%2F&vat=inc&landing-page-category=undefined&is_logged_in=false&curr=GBP

where:

Parameter

Meaning

account ID

is your client account reference.

k

is a content access key/token.

To create an access key/token, expand the User menu and go to Settings > Other Integrations > Fresh Relevance Access Tokens. Select Create Token, and set Mobile for the token type.

url

is the URL of the website to be personalized.

d

is the cookie ID (device ID) for the site visitor.

Sample return from API:

    [
{
_id: "5f31058795a01292bb9340bd",
contentconfig: "1597219117681",
priority: 1,
takeover: false,
name: "New Customers",
dt: "2020-08-10T08:29:59.498Z",
archive_dt: "",
slug: "bnle6al",
archive: false,
content_config_id: "5f33a12d20b0b2d1209d2175"
},
{
_id: "5f3299517c879466ee4e0963",
contentconfig: "1598344540758",
priority: 2,
takeover: false,
name: "Free Delivery",
dt: "2020-08-11T13:12:49.718Z",
archive_dt: "",
slug: "5jhhfqd",
archive: false,
content_config_id: "5f44cd5cfc9af39ef372a2f0"
}
]

Retrieve details about each Slot used on a page

If you need details of how each Slot is placed, then then for each of the above Slots, make the following GET request:

https://dn1i8v75r669j.cloudfront.net/e/?w=[account ID]&id=5f33a12d20b0b2d1209d2175

where:

Parameter

Meaning

account ID

is your client account reference.

id

is the content_config_id returned by the previously described request.

Sample return from API:

    {
rules: {
welcome - morning: [
{
target: {
selector: "#extSvcs"
},
ruleid: "tfd3s1",
dynamic: true,
pageSpec: {
location: [
{
hostname: "www.mysitename.com",
pathname: "/"
}
]
},
position: "append"
}
]
},
k: "xxkeyxx"
}
Did this answer your question?