Email Campaign Recommendation Attribution with the SDK

Overview

Email campaign recommendation attribution lets the browser SDK send a batch_click_on_recommendation event when a user clicks a recommendation in an email campaign and lands on a website page that loads the SDK.

Use this feature when:

  • recommendations are generated for an email/newsletter campaign,

  • the email link points to the normal detail page for the clicked item,

  • the landing page loads the browser SDK,

  • you want the SDK to infer identity, consent state, device/user fields, and clicked item context from the landing page.

The feature only covers the click event after the browser lands on the site. It does not send batch_open or batch_impression, and it does not replace server-side/SFTP batch tracking for offline campaign workflows.

For the product-level batch event contract, see Batch click on recommendation.

URL Payload Contract

The SDK supports these URL payload methods:

For email platforms such as Selligent, prefer simple per-field URL parameters. This avoids JSON construction and base64 encoding inside the email template.

froomle_email_campaign_id=spring-newsletter-2026-05-13
&froomle_email_list_name=weekly_newsletter_recommendations
&froomle_email_request_id=batch-request-12345

A complete landing URL can look like this:

https://www.example.com/articles/123?froomle_email_campaign_id=spring-newsletter-2026-05-13&froomle_email_list_name=weekly_newsletter_recommendations&froomle_email_request_id=batch-request-12345

Required URL parameters:

URL parameter Event field Meaning

froomle_email_campaign_id

campaign_id

Campaign identifier for the batch/email campaign.

froomle_email_list_name

list_name

Recommendation list name used for the campaign recommendations.

froomle_email_request_id

request_id

Identifier of the generated recommendation batch/list result. This must match the batch recommendation output used to create the email links.

Optional URL parameters:

URL parameter Event field Default behavior

froomle_email_action_item

action_item

Optional override for the clicked item id. If omitted, the SDK uses the landing page context_item.

froomle_email_action_item_type

action_item_type

Optional override for the clicked item type. If omitted, the SDK uses the landing page context_item_type; if that is missing, the SDK falls back to article.

froomle_email_channel

channel

Optional override for the event channel. If omitted, the SDK uses email.

Selligent-Style Template Setup

The SDK intentionally supports plain query parameters because Selligent-style templates commonly expose variables and URL helpers such as urlencode(…​), concat(…​), and tracking macros, but not necessarily a base64 encoder.

In that setup, build the link by appending the SDK parameters and URL-encoding each value:

https://www.example.com/articles/123
?froomle_email_campaign_id=[% urlencode([VARIABLE.campaignId]) %]
&froomle_email_list_name=[% urlencode([VARIABLE.listName]) %]
&froomle_email_request_id=[% urlencode([VARIABLE.requestId]) %]

If your Selligent block already computes or appends other tracking parameters, keep those parameters as-is and add the Froomle parameters alongside them. The SDK only reads the froomle_email_* parameters and ignores unrelated campaign/ad-tracking parameters.

For most campaigns, keep the payload minimal and let the SDK infer action_item and action_item_type from the landing page. Use overrides only when the landing page context does not represent the clicked campaign item.

Compact Payload Alternative

Backend-generated links can also use one compact payload parameter:

froomle_email_reco=<base64url-json-payload>

The compact payload is a JSON object encoded as base64url:

{
  "campaign_id": "spring-newsletter-2026-05-13",
  "list_name": "weekly_newsletter_recommendations",
  "request_id": "batch-request-12345"
}
function encodeEmailAttributionPayload(payload) {
  return btoa(JSON.stringify(payload))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/g, '')
}

const payload = encodeEmailAttributionPayload({
  campaign_id: 'spring-newsletter-2026-05-13',
  list_name: 'weekly_newsletter_recommendations',
  request_id: 'batch-request-12345'
})

const href = `https://www.example.com/articles/123?froomle_email_reco=${payload}`

Use the compact payload when you control link generation in code. Use per-field froomle_email_* parameters when links are assembled in an email template tool.

user_group is not part of the SDK URL payload for this feature. The batch click event contract requires campaign_id, list_name, request_id, action_item, and action_item_type. If campaign-level benchmark attribution is needed in the future, document that contract explicitly before adding it to the SDK payload.

Event Sent by the SDK

When all required state is available and consent allows event tracking, the SDK sends:

{
  "event_type": "batch_click_on_recommendation",
  "page_type": "email",
  "action_item": "123",
  "action_item_type": "article",
  "channel": "email",
  "list_name": "weekly_newsletter_recommendations",
  "request_id": "batch-request-12345",
  "campaign_id": "spring-newsletter-2026-05-13",
  "device_id": "...",
  "user_id": "..."
}

Notes:

  • page_type is email for this batch click event, separate from the normal landing page detail_pageview.

  • device_id and user_id follow the normal SDK identity and consent rules.

  • Consent level 0 blocks the batch click event.

  • Consent level 1 allows the event with anonymous identity, according to the normal SDK event policy.

  • Consent level 2 allows identified event tracking when a user_id is configured.

Timing and Deduplication

The SDK queues the email attribution payload until it has enough context to build a valid event.

The SDK waits for:

  • a valid per-field froomle_email_* payload, compact froomle_email_reco payload, or explicit helper call,

  • consent that allows event tracking,

  • context_item or an explicit action_item,

  • context_item_type or an explicit action_item_type.

The SDK deduplicates the event within the current browser tab session. Repeated initialization, React StrictMode re-renders, or router calls with the same payload and landing context should still result in one batch_click_on_recommendation event.

Declarative DOM / Script-Tag

For script-tag integrations, no extra JavaScript call is needed. The SDK reads per-field froomle_email_* parameters or compact froomle_email_reco during initialization and sends the batch click event when page context is ready.

<script
  src="https://cdn.example.com/froomle.global.js"
  data-froomle-env="production"
  data-froomle-page-visit="article_detail"
  data-froomle-context-item="123"
  data-froomle-context-item-type="article"
  data-froomle-user-id="user-456">
</script>

The email link should point to the detail page and include the required per-field froomle_email_* parameters, or the compact froomle_email_reco payload. The normal SDK page tracking can still send detail_pageview for the landing page; the email attribution event remains a separate batch_click_on_recommendation event with page_type: "email".

Module / JavaScript + DOM

For ES module DOM integrations, configure page context first, then call init(). The SDK processes the URL after init() resolves the DOM initialization path.

import {
  init,
  setConsent,
  setContextItem,
  setContextItemType,
  setEnvironment,
  setPageVisit,
  setUserId,
} from '@froomle/frontend-sdk'

setEnvironment('production')
setUserId('user-456')
setConsent(2)
setPageVisit('article_detail')
setContextItem('123')
setContextItemType('article')

await init()

If your route context is not ready at init() time, update setContextItem(…​) and setContextItemType(…​) when it becomes available. The queued email attribution payload is flushed once valid context exists.

Programmatic JS/TS

Programmatic integrations can call the helper explicitly. This is useful when routing is fully application-owned or when you want to process a specific URL after navigation.

import {
  setContextItem,
  setContextItemType,
  setPageVisit,
  trackEmailCampaignRecommendationClickFromUrl,
} from '@froomle/frontend-sdk'

setPageVisit('article_detail')
setContextItem('123')
setContextItemType('article')

trackEmailCampaignRecommendationClickFromUrl(window.location.href)

You can also pass the payload directly:

import { trackEmailCampaignRecommendationClick } from '@froomle/frontend-sdk'

trackEmailCampaignRecommendationClick({
  campaign_id: 'spring-newsletter-2026-05-13',
  list_name: 'weekly_newsletter_recommendations',
  request_id: 'batch-request-12345'
})

Optional override example:

trackEmailCampaignRecommendationClick({
  campaign_id: 'spring-newsletter-2026-05-13',
  list_name: 'weekly_newsletter_recommendations',
  request_id: 'batch-request-12345',
  action_item: 'sku-987',
  action_item_type: 'product',
  channel: 'newsletter'
})

React Bindings

FroomleSdkInit processes the URL during the SDK page-tracking flow. For regular page loads this is automatic.

For SPA route changes, call trackEmailCampaignRecommendationClickFromUrl(…​) after the route has updated the SDK page context. Repeated calls are deduplicated for the same tab/session payload.

import {
  setContextItem,
  setContextItemType,
  setPageVisit,
  trackEmailCampaignRecommendationClickFromUrl,
} from '@froomle/frontend-sdk'

function onArticleRoute(article) {
  setPageVisit('article_detail')
  setContextItem(article.id)
  setContextItemType('article')

  trackEmailCampaignRecommendationClickFromUrl(window.location.href)
}

Unsupported Integration Shapes

The SDK feature requires browser SDK state. It is not available for pure no-SDK/manual integrations where the page does not load @froomle/frontend-sdk.

For no-SDK/manual integrations, send the Events API payload yourself according to Batch click on recommendation. Your implementation must own consent enforcement, identity handling, event validation, retries, and deduplication.

Diagnostics

The browser runtime exposes support diagnostics at:

window.FroomleFrontendSdkRuntime.diagnostics.emailCampaignAttribution

Useful fields include:

Field Meaning

status

Current state, for example idle, detected, pending, blocked, invalid, dispatching, dispatched, error, or duplicate.

source

Where the attribution came from: url:params for per-field URL parameters, url:compact for froomle_email_reco, or programmatic for helper calls.

detectedAt

Timestamp when the SDK detected a URL/helper payload.

paramNames

URL parameter names the SDK associated with the detected payload. This helps verify whether the SDK used Selligent-style per-field parameters or the compact payload.

cleanUrl

Whether the SDK should remove attribution parameters from the browser URL after dispatch. Automatic SDK URL processing leaves this false; explicit helper calls can opt into cleanup.

landingUrlWithoutAttributionParams

Landing URL after removing known Froomle email attribution parameters. This helps compare repeated links without exposing the froomle_email_* payload in diagnostics.

payload

Normalized payload after parsing and alias handling.

validationErrors

Missing or invalid fields, for example missing list_name.

blockedReason

Why the event is not sent yet, such as consent or context-not-ready.

duplicate

true when the SDK suppresses a repeated event for the same tab/session payload.

dedupeKey

Internal deduplication key for support debugging. It combines campaign/list/request/item context and the landing URL without attribution parameters.

dispatchedAt

Timestamp of the most recent successful dispatch.

Use the diagnostics object together with the Froomle Diagnostics Overlay when validating campaign links in a browser.