From a7416ca507a91506f074a377877c84fc811a0dd5 Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Wed, 15 Jan 2025 14:59:49 +0530 Subject: [PATCH 01/15] init --- .../component-info.ts | 43 ++++++ .../personalization-container/helpers.ts | 61 ++++++++ .../blocks/personalization-container/index.ts | 1 + .../personalization-container.lite.tsx | 88 ++++++++++++ .../personalization-container.types.ts | 15 ++ .../builder-registered-components.ts | 6 + .../functions/filter-with-custom-targeting.ts | 133 ++++++++++++++++++ packages/sdks/src/scripts/init-editing.ts | 1 + packages/sdks/src/types/input.ts | 2 +- 9 files changed, 349 insertions(+), 1 deletion(-) create mode 100644 packages/sdks/src/blocks/personalization-container/component-info.ts create mode 100644 packages/sdks/src/blocks/personalization-container/helpers.ts create mode 100644 packages/sdks/src/blocks/personalization-container/index.ts create mode 100644 packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx create mode 100644 packages/sdks/src/blocks/personalization-container/personalization-container.types.ts create mode 100644 packages/sdks/src/functions/filter-with-custom-targeting.ts diff --git a/packages/sdks/src/blocks/personalization-container/component-info.ts b/packages/sdks/src/blocks/personalization-container/component-info.ts new file mode 100644 index 00000000000..7aceceb6a68 --- /dev/null +++ b/packages/sdks/src/blocks/personalization-container/component-info.ts @@ -0,0 +1,43 @@ +import type { ComponentInfo } from '../../types/components.js'; + +export const componentInfo: ComponentInfo = { + name: 'PersonalizationContainer', + noWrap: true, + image: + 'https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F37229ed30d8c41dfb10b8cca1992053a', + canHaveChildren: true, + inputs: [ + { + name: 'variants', + defaultValue: [], + behavior: 'personalizationVariantList', + type: 'list', + subFields: [ + { + name: 'name', + type: 'text', + }, + { + name: 'query', + friendlyName: 'Targeting rules', + type: 'BuilderQuery', + defaultValue: [], + }, + { + name: 'startDate', + type: 'date', + }, + { + name: 'endDate', + type: 'date', + }, + { + name: 'blocks', + type: 'uiBlocks', + hideFromUI: true, + defaultValue: [], + }, + ], + }, + ], +}; diff --git a/packages/sdks/src/blocks/personalization-container/helpers.ts b/packages/sdks/src/blocks/personalization-container/helpers.ts new file mode 100644 index 00000000000..7f17f148596 --- /dev/null +++ b/packages/sdks/src/blocks/personalization-container/helpers.ts @@ -0,0 +1,61 @@ +import { filterWithCustomTargetingScript } from '../../functions/filter-with-custom-targeting'; +import type { PersonalizationContainerProps } from './personalization-container.types'; + +export function getPersonalizationScript( + variants: PersonalizationContainerProps['variants'], + blockId?: string +) { + return ` + (function() { + function getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); + } + return null; + } + function removeVariants() { + variants.forEach(function (template, index) { + document.querySelector('template[data-variant-id="' + "${blockId}" + index + '"]').remove(); + }); + document.getElementById('variants-script-${blockId}').remove(); + } + var attributes = JSON.parse(getCookie("${'builder.userAttributes'}") || "{}"); + var variants = ${JSON.stringify(variants?.map((v) => ({ query: v.query, startDate: v.startDate, endDate: v.endDate })))}; + var winningVariantIndex = variants.findIndex(function(variant) { + return filterWithCustomTargeting( + attributes, + variant.query, + variant.startDate, + variant.endDate + ); + }); + var isDebug = location.href.includes('builder.debug=true'); + if (isDebug) { + console.debug('PersonalizationContainer', { + attributes: attributes, + variants: variants, + winningVariantIndex: winningVariantIndex, + }); + } + if (winningVariantIndex !== -1) { + var winningVariant = document.querySelector('template[data-variant-id="' + "${blockId}" + winningVariantIndex + '"]'); + if (winningVariant) { + var parentNode = winningVariant.parentNode; + var newParent = parentNode.cloneNode(false); + newParent.appendChild(winningVariant.content.firstChild); + parentNode.parentNode.replaceChild(newParent, parentNode); + if (isDebug) { + console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); + } + } + } else if (variants.length > 0) { + removeVariants(); + } + ${filterWithCustomTargetingScript} + })(); + `.replace(/\s+/g, ' '); +} diff --git a/packages/sdks/src/blocks/personalization-container/index.ts b/packages/sdks/src/blocks/personalization-container/index.ts new file mode 100644 index 00000000000..3bfb2c09fa0 --- /dev/null +++ b/packages/sdks/src/blocks/personalization-container/index.ts @@ -0,0 +1 @@ +export { default } from './personalization-container.lite.jsx'; diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx new file mode 100644 index 00000000000..88e5eb9c28a --- /dev/null +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -0,0 +1,88 @@ +import { onMount, Show, useMetadata, useStore } from '@builder.io/mitosis'; +import Blocks from '../../components/blocks/blocks.lite.jsx'; +import InlinedScript from '../../components/inlined-script.lite.jsx'; +import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; +import { isEditing } from '../../functions/is-editing.js'; +import { getPersonalizationScript } from './helpers.js'; +import type { PersonalizationContainerProps } from './personalization-container.types.js'; + +useMetadata({ + rsc: { + componentType: 'client', + }, +}); + +export default function PersonalizationContainer( + props: PersonalizationContainerProps +) { + const state = useStore({ + isClient: false, + get filteredVariants() { + return (props.variants || []).filter((variant) => { + return filterWithCustomTargeting( + { + ...({} as any), + }, + variant.query, + variant.startDate, + variant.endDate + ); + }); + }, + get winningVariant() { + return state.filteredVariants[0]; + }, + }); + + onMount(() => { + state.isClient = true; + }); + + return ( +
+ + + + + } + > + + +
+ ); +} diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.types.ts b/packages/sdks/src/blocks/personalization-container/personalization-container.types.ts new file mode 100644 index 00000000000..fbc1e2a0930 --- /dev/null +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.types.ts @@ -0,0 +1,15 @@ +import type { Query } from '../../functions/filter-with-custom-targeting.js'; +import type { BuilderBlock } from '../../types/builder-block.js'; +import type { BuilderDataProps } from '../../types/builder-props.js'; + +export type PersonalizationContainerProps = { + children?: any; + attributes?: any; + previewingIndex?: number | null; + variants?: Array<{ + blocks: BuilderBlock[]; + query: Query[]; + startDate?: string; + endDate?: string; + }>; +} & BuilderDataProps; diff --git a/packages/sdks/src/constants/builder-registered-components.ts b/packages/sdks/src/constants/builder-registered-components.ts index 915b829262f..859423bbc9e 100644 --- a/packages/sdks/src/constants/builder-registered-components.ts +++ b/packages/sdks/src/constants/builder-registered-components.ts @@ -8,6 +8,8 @@ import { componentInfo as fragmentComponentInfo } from '../blocks/fragment/compo import { default as Fragment } from '../blocks/fragment/index.js'; import { componentInfo as imageComponentInfo } from '../blocks/image/component-info.js'; import { default as Image } from '../blocks/image/index.js'; +import { componentInfo as personalizationContainerComponentInfo } from '../blocks/personalization-container/component-info.js'; +import { default as PersonalizationContainer } from '../blocks/personalization-container/index.js'; import { componentInfo as sectionComponentInfo } from '../blocks/section/component-info.js'; import { default as Section } from '../blocks/section/index.js'; import { componentInfo as slotComponentInfo } from '../blocks/slot/component-info.js'; @@ -36,6 +38,10 @@ export const getDefaultRegisteredComponents: () => RegisteredComponent[] = { component: Slot, ...slotComponentInfo }, { component: Symbol, ...symbolComponentInfo }, { component: Text, ...textComponentInfo }, + { + component: PersonalizationContainer, + ...personalizationContainerComponentInfo, + }, ...(TARGET === 'rsc' ? [] : [ diff --git a/packages/sdks/src/functions/filter-with-custom-targeting.ts b/packages/sdks/src/functions/filter-with-custom-targeting.ts new file mode 100644 index 00000000000..a1f75c0b81f --- /dev/null +++ b/packages/sdks/src/functions/filter-with-custom-targeting.ts @@ -0,0 +1,133 @@ +type UserAttributes = { + date?: string | Date; + urlPath?: string; + [key: string]: any; // Allow any other properties +}; + +// Query type +type QueryOperator = + | 'is' + | 'isNot' + | 'contains' + | 'startsWith' + | 'endsWith' + | 'greaterThan' + | 'lessThan' + | 'greaterThanOrEqualTo' + | 'lessThanOrEqualTo'; + +type QueryValue = string | number | boolean | Array; + +export type Query = { + property: string; + operator: QueryOperator; + value: QueryValue; +}; + +// minified version of the function need to be added to the script +export const filterWithCustomTargetingScript = `function filterWithCustomTargeting(e,t,n,r){var i={query:t,startDate:n,endDate:r},o=e.date&&new Date(e.date)||new Date;return!(i.startDate&&new Date(i.startDate)>o)&&(!(i.endDate&&new Date(i.endDate)i;case"lessThan":return isNumber(o)&&isNumber(i)&&o=i;case"lessThanOrEqualTo":return isNumber(o)&&isNumber(i)&&o<=i}return!1}()}`; + +export function filterWithCustomTargeting( + userAttributes: UserAttributes, + query: Query[], + startDate?: string, + endDate?: string +) { + const item = { + query, + startDate, + endDate, + }; + + const now = + (userAttributes.date && new Date(userAttributes.date)) || new Date(); + + if (item.startDate && new Date(item.startDate) > now) { + return false; + } else if (item.endDate && new Date(item.endDate) < now) { + return false; + } + + if (!item.query || !item.query.length) { + return true; + } + + return item.query.every((filter: Query) => { + return objectMatchesQuery(userAttributes, filter); + }); +} + +function isString(val: unknown): val is string { + return typeof val === 'string'; +} + +function isNumber(val: unknown): val is number { + return typeof val === 'number'; +} + +function objectMatchesQuery(userattr: UserAttributes, query: Query): boolean { + const result = (() => { + const property = query.property; + const operator = query.operator; + let testValue = query.value; + + if ( + query && + query.property === 'urlPath' && + query.value && + typeof query.value === 'string' && + query.value !== '/' && + query.value.endsWith('/') + ) { + testValue = query.value.slice(0, -1); + } + + // Check is query property is present in userAttributes. Proceed only if it is present. + if (!(property && operator)) { + return true; + } + + if (Array.isArray(testValue)) { + if (operator === 'isNot') { + return testValue.every((val) => + objectMatchesQuery(userattr, { property, operator, value: val }) + ); + } + return !!testValue.find((val) => + objectMatchesQuery(userattr, { property, operator, value: val }) + ); + } + const value = userattr[property]; + + if (Array.isArray(value)) { + return value.includes(testValue); + } + + switch (operator) { + case 'is': + return value === testValue; + case 'isNot': + return value !== testValue; + case 'contains': + return ( + (isString(value) || Array.isArray(value)) && + value.includes(String(testValue)) + ); + case 'startsWith': + return isString(value) && value.startsWith(String(testValue)); + case 'endsWith': + return isString(value) && value.endsWith(String(testValue)); + case 'greaterThan': + return isNumber(value) && isNumber(testValue) && value > testValue; + case 'lessThan': + return isNumber(value) && isNumber(testValue) && value < testValue; + case 'greaterThanOrEqualTo': + return isNumber(value) && isNumber(testValue) && value >= testValue; + case 'lessThanOrEqualTo': + return isNumber(value) && isNumber(testValue) && value <= testValue; + } + return false; + })(); + + return result; +} diff --git a/packages/sdks/src/scripts/init-editing.ts b/packages/sdks/src/scripts/init-editing.ts index d75a29a5798..52ed4babd15 100644 --- a/packages/sdks/src/scripts/init-editing.ts +++ b/packages/sdks/src/scripts/init-editing.ts @@ -50,6 +50,7 @@ export const setupBrowserForEditing = ( // scope our '+ add block' button styling supportsAddBlockScoping: true, supportsCustomBreakpoints: true, + blockLevelPersonalization: true, }, }, '*' diff --git a/packages/sdks/src/types/input.ts b/packages/sdks/src/types/input.ts index c5e93d4b36b..c69e7d518ae 100644 --- a/packages/sdks/src/types/input.ts +++ b/packages/sdks/src/types/input.ts @@ -117,7 +117,7 @@ export interface Input { * Use optionally with inputs of type `reference`. Restricts the content entry picker to a specific model by name. */ model?: string; - + behavior?: string; valueType?: { type?: string; }; From 966ff90d4b84857ed4b971787171098f301b67c4 Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Thu, 16 Jan 2025 11:58:21 +0530 Subject: [PATCH 02/15] f --- .../component-info.ts | 4 + .../personalization-container/helpers.ts | 102 +++++++++--------- .../personalization-container.lite.tsx | 84 +++++++++++---- packages/sdks/src/helpers/canTrack.ts | 8 +- packages/sdks/src/helpers/user-attributes.ts | 46 ++++++++ .../sdks/src/index-helpers/blocks-exports.ts | 2 + 6 files changed, 172 insertions(+), 74 deletions(-) create mode 100644 packages/sdks/src/helpers/user-attributes.ts diff --git a/packages/sdks/src/blocks/personalization-container/component-info.ts b/packages/sdks/src/blocks/personalization-container/component-info.ts index 7aceceb6a68..7a65b1f0ab5 100644 --- a/packages/sdks/src/blocks/personalization-container/component-info.ts +++ b/packages/sdks/src/blocks/personalization-container/component-info.ts @@ -2,6 +2,10 @@ import type { ComponentInfo } from '../../types/components.js'; export const componentInfo: ComponentInfo = { name: 'PersonalizationContainer', + shouldReceiveBuilderProps: { + builderBlock: true, + builderContext: true, + }, noWrap: true, image: 'https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F37229ed30d8c41dfb10b8cca1992053a', diff --git a/packages/sdks/src/blocks/personalization-container/helpers.ts b/packages/sdks/src/blocks/personalization-container/helpers.ts index 7f17f148596..3891a54da08 100644 --- a/packages/sdks/src/blocks/personalization-container/helpers.ts +++ b/packages/sdks/src/blocks/personalization-container/helpers.ts @@ -1,61 +1,65 @@ import { filterWithCustomTargetingScript } from '../../functions/filter-with-custom-targeting'; +import { USER_ATTRIBUTES_COOKIE_NAME } from '../../helpers/user-attributes.js'; import type { PersonalizationContainerProps } from './personalization-container.types'; export function getPersonalizationScript( variants: PersonalizationContainerProps['variants'], - blockId?: string + blockId: string, + locale?: string ) { return ` - (function() { - function getCookie(name) { - var nameEQ = name + "="; - var ca = document.cookie.split(';'); - for(var i=0;i < ca.length;i++) { - var c = ca[i]; - while (c.charAt(0)==' ') c = c.substring(1,c.length); - if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); - } - return null; - } - function removeVariants() { - variants.forEach(function (template, index) { - document.querySelector('template[data-variant-id="' + "${blockId}" + index + '"]').remove(); - }); - document.getElementById('variants-script-${blockId}').remove(); + (function() { + function getCookie(name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for(var i=0;i < ca.length;i++) { + var c = ca[i]; + while (c.charAt(0)==' ') c = c.substring(1,c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } - var attributes = JSON.parse(getCookie("${'builder.userAttributes'}") || "{}"); - var variants = ${JSON.stringify(variants?.map((v) => ({ query: v.query, startDate: v.startDate, endDate: v.endDate })))}; - var winningVariantIndex = variants.findIndex(function(variant) { - return filterWithCustomTargeting( - attributes, - variant.query, - variant.startDate, - variant.endDate - ); + return null; + } + function removeVariants() { + variants.forEach(function (template, index) { + document.querySelector('template[data-variant-id="' + "${blockId}" + index + '"]').remove(); }); - var isDebug = location.href.includes('builder.debug=true'); - if (isDebug) { - console.debug('PersonalizationContainer', { - attributes: attributes, - variants: variants, - winningVariantIndex: winningVariantIndex, - }); - } - if (winningVariantIndex !== -1) { - var winningVariant = document.querySelector('template[data-variant-id="' + "${blockId}" + winningVariantIndex + '"]'); - if (winningVariant) { - var parentNode = winningVariant.parentNode; - var newParent = parentNode.cloneNode(false); - newParent.appendChild(winningVariant.content.firstChild); - parentNode.parentNode.replaceChild(newParent, parentNode); - if (isDebug) { - console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); - } + document.getElementById('variants-script-${blockId}').remove(); + } + + var attributes = JSON.parse(getCookie("${USER_ATTRIBUTES_COOKIE_NAME}") || "{}"); + ${locale ? `attributes.locale = "${locale}";` : ''} + var variants = ${JSON.stringify(variants?.map((v) => ({ query: v.query, startDate: v.startDate, endDate: v.endDate })))}; + var winningVariantIndex = variants.findIndex(function(variant) { + return filterWithCustomTargeting( + attributes, + variant.query, + variant.startDate, + variant.endDate + ); + }); + var isDebug = location.href.includes('builder.debug=true'); + if (isDebug) { + console.debug('PersonalizationContainer', { + attributes: attributes, + variants: variants, + winningVariantIndex: winningVariantIndex, + }); + } + if (winningVariantIndex !== -1) { + var winningVariant = document.querySelector('template[data-variant-id="' + "${blockId}" + winningVariantIndex + '"]'); + if (winningVariant) { + var parentNode = winningVariant.parentNode; + var newParent = parentNode.cloneNode(false); + newParent.appendChild(winningVariant.content.firstChild); + parentNode.parentNode.replaceChild(newParent, parentNode); + if (isDebug) { + console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); } - } else if (variants.length > 0) { - removeVariants(); } - ${filterWithCustomTargetingScript} - })(); - `.replace(/\s+/g, ' '); + } else if (variants.length > 0) { + removeVariants(); + } + ${filterWithCustomTargetingScript} + })(); + `.replace(/\s+/g, ' '); } diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 88e5eb9c28a..2b95c6be088 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,8 +1,9 @@ -import { onMount, Show, useMetadata, useStore } from '@builder.io/mitosis'; +import { For, onMount, Show, useMetadata, useStore } from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; import { isEditing } from '../../functions/is-editing.js'; +import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; import { getPersonalizationScript } from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; @@ -21,7 +22,10 @@ export default function PersonalizationContainer( return (props.variants || []).filter((variant) => { return filterWithCustomTargeting( { - ...({} as any), + ...(props.builderContext.value?.rootState?.locale + ? { locale: props.builderContext.value?.rootState?.locale } + : {}), + ...(userAttributesSubscriber.getUserAttributes() as any), }, variant.query, variant.startDate, @@ -54,34 +58,68 @@ export default function PersonalizationContainer( nonce={props.builderContext.value?.nonce || ''} scriptStr={getPersonalizationScript( props.variants, - props.builderBlock?.id + props.builderBlock?.id || 'none', + props.builderContext.value?.rootState?.locale as string | undefined )} id={`variants-script-${props.builderBlock?.id}`} /> - - + <> + + {(variant, index) => ( + + )} + + {props.children} + } > - + + } + > + {props.children} + + } + > + + ); diff --git a/packages/sdks/src/helpers/canTrack.ts b/packages/sdks/src/helpers/canTrack.ts index db8b4d33e66..5597d2b629b 100644 --- a/packages/sdks/src/helpers/canTrack.ts +++ b/packages/sdks/src/helpers/canTrack.ts @@ -1,4 +1,8 @@ import { checkIsDefined } from './nullable.js'; +import { userAttributesSubscriber } from './user-attributes.js'; -export const getDefaultCanTrack = (canTrack?: boolean) => - checkIsDefined(canTrack) ? canTrack : true; +export const getDefaultCanTrack = (canTrack?: boolean) => { + const result = checkIsDefined(canTrack) ? canTrack : true; + userAttributesSubscriber.setCanTrack(result); + return result; +}; diff --git a/packages/sdks/src/helpers/user-attributes.ts b/packages/sdks/src/helpers/user-attributes.ts new file mode 100644 index 00000000000..3a919ade4cf --- /dev/null +++ b/packages/sdks/src/helpers/user-attributes.ts @@ -0,0 +1,46 @@ +import { getCookieSync, setCookie } from './cookie.js'; + +export interface UserAttributes { + [key: string]: any; +} + +export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes'; + +export function createUserAttributesSubscriber() { + let canTrack = true; + const subscribers = new Set<(attrs: UserAttributes) => void>(); + return { + setUserAttributes(newAttrs: UserAttributes) { + const userAttributes: UserAttributes = { + ...this.getUserAttributes(), + ...newAttrs, + }; + setCookie({ + name: USER_ATTRIBUTES_COOKIE_NAME, + value: JSON.stringify(userAttributes), + canTrack, + }); + subscribers.forEach((callback) => callback(userAttributes)); + }, + getUserAttributes() { + return JSON.parse( + getCookieSync({ name: USER_ATTRIBUTES_COOKIE_NAME, canTrack }) || '{}' + ); + }, + subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void) { + subscribers.add(callback); + return () => { + subscribers.delete(callback); + }; + }, + setCanTrack(value: boolean) { + canTrack = value; + }, + }; +} + +export const userAttributesSubscriber = createUserAttributesSubscriber(); + +export const setClientUserAttributes = (attributes: UserAttributes) => { + userAttributesSubscriber.setUserAttributes(attributes); +}; diff --git a/packages/sdks/src/index-helpers/blocks-exports.ts b/packages/sdks/src/index-helpers/blocks-exports.ts index ab797ff032b..ad5aa917c1d 100644 --- a/packages/sdks/src/index-helpers/blocks-exports.ts +++ b/packages/sdks/src/index-helpers/blocks-exports.ts @@ -13,3 +13,5 @@ export { default as Content } from '../components/content-variants/index.js'; * Builder Context */ export { BuilderContext } from '../context/index.js'; + +export { setClientUserAttributes } from '../helpers/user-attributes.js'; From 6359fa999c634c41a11209ab4149ed747e91763f Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Thu, 16 Jan 2025 16:23:08 +0530 Subject: [PATCH 03/15] try --- .../personalization-container/helpers.ts | 4 +- .../personalization-container.lite.tsx | 58 +++++++++++++------ .../content-variants.lite.tsx | 2 +- .../components/content-variants/helpers.ts | 8 ++- 4 files changed, 47 insertions(+), 25 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/helpers.ts b/packages/sdks/src/blocks/personalization-container/helpers.ts index 3891a54da08..15616291ea6 100644 --- a/packages/sdks/src/blocks/personalization-container/helpers.ts +++ b/packages/sdks/src/blocks/personalization-container/helpers.ts @@ -21,7 +21,7 @@ export function getPersonalizationScript( } function removeVariants() { variants.forEach(function (template, index) { - document.querySelector('template[data-variant-id="' + "${blockId}" + index + '"]').remove(); + document.querySelector('div[data-variant-id="' + "${blockId}-" + index + '"]').remove(); }); document.getElementById('variants-script-${blockId}').remove(); } @@ -46,7 +46,7 @@ export function getPersonalizationScript( }); } if (winningVariantIndex !== -1) { - var winningVariant = document.querySelector('template[data-variant-id="' + "${blockId}" + winningVariantIndex + '"]'); + var winningVariant = document.querySelector('div[data-variant-id="' + "${blockId}-" + winningVariantIndex + '"]'); if (winningVariant) { var parentNode = winningVariant.parentNode; var newParent = parentNode.cloneNode(false); diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 2b95c6be088..2b743b9dbc6 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,8 +1,11 @@ import { For, onMount, Show, useMetadata, useStore } from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; +import { checkShouldRenderVariants } from '../../components/content-variants/helpers.js'; import InlinedScript from '../../components/inlined-script.lite.jsx'; +import InlinedStyles from '../../components/inlined-styles.lite.jsx'; import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; import { isEditing } from '../../functions/is-editing.js'; +import { getDefaultCanTrack } from '../../helpers/canTrack.js'; import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; import { getPersonalizationScript } from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; @@ -17,7 +20,11 @@ export default function PersonalizationContainer( props: PersonalizationContainerProps ) { const state = useStore({ - isClient: false, + isMounted: false, + shouldRenderVariants: checkShouldRenderVariants({ + canTrack: getDefaultCanTrack(props.builderContext.value?.canTrack), + hasVariants: Boolean(props.variants?.length), + }), get filteredVariants() { return (props.variants || []).filter((variant) => { return filterWithCustomTargeting( @@ -36,40 +43,53 @@ export default function PersonalizationContainer( get winningVariant() { return state.filteredVariants[0]; }, + get hideVariantsStyleString() { + return (props.variants || []) + .map( + (_, index) => + `[data-variant-id="${props.builderBlock?.id}-${index}"] { display: none; } ` + ) + .join(''); + }, }); onMount(() => { - state.isClient = true; + state.isMounted = true; }); return (
- + + {(variant, index) => ( - +
)} {props.children} @@ -95,7 +115,7 @@ export default function PersonalizationContainer( ) => export const checkShouldRenderVariants = ({ canTrack, - content, + // content, + hasVariants, }: { canTrack: Nullable; - content: Nullable; + hasVariants: boolean; + // content: Nullable; }) => { - const hasVariants = getVariants(content).length > 0; + // const hasVariants = getVariants(content).length > 0; /** * We cannot SSR in React-Native. From 2ca5359f70a7a72bf195dddea188cc01af26a85a Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Thu, 16 Jan 2025 19:53:45 +0530 Subject: [PATCH 04/15] fix --- .../personalization-container.lite.tsx | 7 +------ .../components/content-variants/content-variants.lite.tsx | 2 +- packages/sdks/src/components/content-variants/helpers.ts | 8 +++----- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 2b743b9dbc6..cc6a6e24a18 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,11 +1,9 @@ import { For, onMount, Show, useMetadata, useStore } from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; -import { checkShouldRenderVariants } from '../../components/content-variants/helpers.js'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; import { isEditing } from '../../functions/is-editing.js'; -import { getDefaultCanTrack } from '../../helpers/canTrack.js'; import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; import { getPersonalizationScript } from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; @@ -21,10 +19,7 @@ export default function PersonalizationContainer( ) { const state = useStore({ isMounted: false, - shouldRenderVariants: checkShouldRenderVariants({ - canTrack: getDefaultCanTrack(props.builderContext.value?.canTrack), - hasVariants: Boolean(props.variants?.length), - }), + shouldRenderVariants: typeof window === 'undefined', get filteredVariants() { return (props.variants || []).filter((variant) => { return filterWithCustomTargeting( diff --git a/packages/sdks/src/components/content-variants/content-variants.lite.tsx b/packages/sdks/src/components/content-variants/content-variants.lite.tsx index b5b10276cca..69939737ae2 100644 --- a/packages/sdks/src/components/content-variants/content-variants.lite.tsx +++ b/packages/sdks/src/components/content-variants/content-variants.lite.tsx @@ -57,7 +57,7 @@ export default function ContentVariants(props: VariantsProviderProps) { const state = useStore({ shouldRenderVariants: checkShouldRenderVariants({ canTrack: getDefaultCanTrack(props.canTrack), - hasVariants: Boolean(props.content?.variations?.length), + content: props.content, }), get updateCookieAndStylesScriptStr() { return getUpdateCookieAndStylesScript( diff --git a/packages/sdks/src/components/content-variants/helpers.ts b/packages/sdks/src/components/content-variants/helpers.ts index d3df2aa30e5..32da6e632c1 100644 --- a/packages/sdks/src/components/content-variants/helpers.ts +++ b/packages/sdks/src/components/content-variants/helpers.ts @@ -26,14 +26,12 @@ export const getVariants = (content: Nullable) => export const checkShouldRenderVariants = ({ canTrack, - // content, - hasVariants, + content, }: { canTrack: Nullable; - hasVariants: boolean; - // content: Nullable; + content: Nullable; }) => { - // const hasVariants = getVariants(content).length > 0; + const hasVariants = getVariants(content).length > 0; /** * We cannot SSR in React-Native. From b17d1f4314d3eb5d83bbbd71174d4ec8a0c7d362 Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Fri, 17 Jan 2025 16:26:14 +0530 Subject: [PATCH 05/15] try --- .../personalization-container/helpers.ts | 16 ++- .../personalization-container.lite.tsx | 128 ++++++++---------- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/helpers.ts b/packages/sdks/src/blocks/personalization-container/helpers.ts index 15616291ea6..1e75458bc5e 100644 --- a/packages/sdks/src/blocks/personalization-container/helpers.ts +++ b/packages/sdks/src/blocks/personalization-container/helpers.ts @@ -1,7 +1,6 @@ import { filterWithCustomTargetingScript } from '../../functions/filter-with-custom-targeting'; -import { USER_ATTRIBUTES_COOKIE_NAME } from '../../helpers/user-attributes.js'; +import { USER_ATTRIBUTES_COOKIE_NAME } from '../../helpers/user-attributes'; import type { PersonalizationContainerProps } from './personalization-container.types'; - export function getPersonalizationScript( variants: PersonalizationContainerProps['variants'], blockId: string, @@ -21,14 +20,22 @@ export function getPersonalizationScript( } function removeVariants() { variants.forEach(function (template, index) { + console.log("removing variant", "${blockId}-" + index); document.querySelector('div[data-variant-id="' + "${blockId}-" + index + '"]').remove(); }); + console.log("removing variants script"); document.getElementById('variants-script-${blockId}').remove(); } var attributes = JSON.parse(getCookie("${USER_ATTRIBUTES_COOKIE_NAME}") || "{}"); ${locale ? `attributes.locale = "${locale}";` : ''} - var variants = ${JSON.stringify(variants?.map((v) => ({ query: v.query, startDate: v.startDate, endDate: v.endDate })))}; + var variants = ${JSON.stringify( + variants?.map((v) => ({ + query: v.query, + startDate: v.startDate, + endDate: v.endDate, + })) + )}; var winningVariantIndex = variants.findIndex(function(variant) { return filterWithCustomTargeting( attributes, @@ -47,10 +54,11 @@ export function getPersonalizationScript( } if (winningVariantIndex !== -1) { var winningVariant = document.querySelector('div[data-variant-id="' + "${blockId}-" + winningVariantIndex + '"]'); + console.log("winningVariant", winningVariant); if (winningVariant) { var parentNode = winningVariant.parentNode; var newParent = parentNode.cloneNode(false); - newParent.appendChild(winningVariant.content.firstChild); + newParent.appendChild(winningVariant.firstChild); parentNode.parentNode.replaceChild(newParent, parentNode); if (isDebug) { console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index cc6a6e24a18..082ad2f06d9 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -19,7 +19,6 @@ export default function PersonalizationContainer( ) { const state = useStore({ isMounted: false, - shouldRenderVariants: typeof window === 'undefined', get filteredVariants() { return (props.variants || []).filter((variant) => { return filterWithCustomTargeting( @@ -56,86 +55,75 @@ export default function PersonalizationContainer(
+ + {(variant, index) => ( +
+ +
+ )} +
- - - - {(variant, index) => ( -
- -
- )} -
+ + } + > {props.children} - + } > - - } - > - {props.children} - - } - > - -
+ + +
); } From c40d98901be4ecdbebae0a388cbfa54f0cebffde Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 15:25:54 +0530 Subject: [PATCH 06/15] checkpoint --- .../src/blocks/PersonalizationContainer.tsx | 20 ++- .../personalization-container/helpers.ts | 14 +- .../personalization-container.lite.tsx | 128 ++++++++++-------- packages/sdks/src/helpers/user-attributes.ts | 7 + 4 files changed, 105 insertions(+), 64 deletions(-) diff --git a/packages/react/src/blocks/PersonalizationContainer.tsx b/packages/react/src/blocks/PersonalizationContainer.tsx index c73eb6f929c..82bd771467e 100644 --- a/packages/react/src/blocks/PersonalizationContainer.tsx +++ b/packages/react/src/blocks/PersonalizationContainer.tsx @@ -144,6 +144,16 @@ export function PersonalizationContainer(props: PersonalizationContainerProps) { ); }); + console.log( + 'here', + Builder.isBrowser, + Builder.isEditing, + Builder.isServer, + props.previewingIndex, + filteredVariants.length, + isClient + ); + return (
{/* If editing a specific varient */} {Builder.isEditing && @@ -298,6 +308,14 @@ function getPersonalizationScript( var parentNode = winningVariant.parentNode; var newParent = parentNode.cloneNode(false); newParent.appendChild(winningVariant.content.firstChild); + console.log('newParent', { + parentNode: parentNode, + newParent: newParent, + winningVariant: winningVariant, + firstChild: winningVariant.content.firstChild, + lastChild: winningVariant.content.lastChild, + content: winningVariant.content, + }); parentNode.parentNode.replaceChild(newParent, parentNode); if (isDebug) { console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); diff --git a/packages/sdks/src/blocks/personalization-container/helpers.ts b/packages/sdks/src/blocks/personalization-container/helpers.ts index 1e75458bc5e..21ed0b7b8d0 100644 --- a/packages/sdks/src/blocks/personalization-container/helpers.ts +++ b/packages/sdks/src/blocks/personalization-container/helpers.ts @@ -8,6 +8,10 @@ export function getPersonalizationScript( ) { return ` (function() { + if (!navigator.cookieEnabled) { + return; + } + function getCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); @@ -21,10 +25,11 @@ export function getPersonalizationScript( function removeVariants() { variants.forEach(function (template, index) { console.log("removing variant", "${blockId}-" + index); - document.querySelector('div[data-variant-id="' + "${blockId}-" + index + '"]').remove(); + document.querySelector('template[data-variant-id="' + "${blockId}-" + index + '"]').remove(); }); console.log("removing variants script"); - document.getElementById('variants-script-${blockId}').remove(); + document.querySelector('script[data-id="variants-script-${blockId}"]').remove(); + document.querySelector('style[data-id="variants-styles-${blockId}"]').remove(); } var attributes = JSON.parse(getCookie("${USER_ATTRIBUTES_COOKIE_NAME}") || "{}"); @@ -53,12 +58,13 @@ export function getPersonalizationScript( }); } if (winningVariantIndex !== -1) { - var winningVariant = document.querySelector('div[data-variant-id="' + "${blockId}-" + winningVariantIndex + '"]'); + var winningVariant = document.querySelector('template[data-variant-id="' + "${blockId}-" + winningVariantIndex + '"]'); console.log("winningVariant", winningVariant); if (winningVariant) { var parentNode = winningVariant.parentNode; var newParent = parentNode.cloneNode(false); - newParent.appendChild(winningVariant.firstChild); + newParent.appendChild(winningVariant.content.firstChild); + newParent.appendChild(winningVariant.content.lastChild); parentNode.parentNode.replaceChild(newParent, parentNode); if (isDebug) { console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 082ad2f06d9..f2b76885377 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,4 +1,10 @@ -import { For, onMount, Show, useMetadata, useStore } from '@builder.io/mitosis'; +import { + For, + Fragment, + Show, + useMetadata, + useStore, +} from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; @@ -18,7 +24,6 @@ export default function PersonalizationContainer( props: PersonalizationContainerProps ) { const state = useStore({ - isMounted: false, get filteredVariants() { return (props.variants || []).filter((variant) => { return filterWithCustomTargeting( @@ -47,69 +52,66 @@ export default function PersonalizationContainer( }, }); - onMount(() => { - state.isMounted = true; - }); - return ( -
- - {(variant, index) => ( -
- -
- )} -
- +
+ + + {(variant, index) => ( + + )} + + + + } + > - } - > - {props.children} - - } - > - - + + } + > + + +
-
+ + ); } diff --git a/packages/sdks/src/helpers/user-attributes.ts b/packages/sdks/src/helpers/user-attributes.ts index 3a919ade4cf..87c9d524dd4 100644 --- a/packages/sdks/src/helpers/user-attributes.ts +++ b/packages/sdks/src/helpers/user-attributes.ts @@ -1,3 +1,4 @@ +import { isBrowser } from '../functions/is-browser.js'; import { getCookieSync, setCookie } from './cookie.js'; export interface UserAttributes { @@ -11,6 +12,9 @@ export function createUserAttributesSubscriber() { const subscribers = new Set<(attrs: UserAttributes) => void>(); return { setUserAttributes(newAttrs: UserAttributes) { + if (!isBrowser()) { + return; + } const userAttributes: UserAttributes = { ...this.getUserAttributes(), ...newAttrs, @@ -23,6 +27,9 @@ export function createUserAttributesSubscriber() { subscribers.forEach((callback) => callback(userAttributes)); }, getUserAttributes() { + if (!isBrowser()) { + return {}; + } return JSON.parse( getCookieSync({ name: USER_ATTRIBUTES_COOKIE_NAME, canTrack }) || '{}' ); From 9623628d48495abe0362dcfc7f9f435824f2438c Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 15:26:38 +0530 Subject: [PATCH 07/15] remove --- .../personalization-container.lite.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index f2b76885377..98e20a34b62 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -126,14 +126,6 @@ export default function PersonalizationContainer( )} id={`variants-script-${props.builderBlock?.id}`} /> - ); } From bcfae30a289a26d85a5e2a8f9bfde41450d611ec Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 15:36:36 +0530 Subject: [PATCH 08/15] fix --- .../personalization-container.lite.tsx | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 98e20a34b62..f2ab7730c3d 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -9,7 +9,6 @@ import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; -import { isEditing } from '../../functions/is-editing.js'; import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; import { getPersonalizationScript } from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; @@ -78,16 +77,31 @@ export default function PersonalizationContainer( )} + +
- - ); } From fead5dfa2b68e81f410eeaf4e372fa5eebf95f7f Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 15:36:58 +0530 Subject: [PATCH 09/15] fix --- .../personalization-container.lite.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index f2ab7730c3d..97ac7b22f93 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,10 +1,4 @@ -import { - For, - Fragment, - Show, - useMetadata, - useStore, -} from '@builder.io/mitosis'; +import { For, Fragment, Show, useStore } from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; @@ -13,12 +7,6 @@ import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; import { getPersonalizationScript } from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; -useMetadata({ - rsc: { - componentType: 'client', - }, -}); - export default function PersonalizationContainer( props: PersonalizationContainerProps ) { From 0f3820f2d6abc06140039e7a3016093e18566ca0 Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 15:37:14 +0530 Subject: [PATCH 10/15] fix --- .../personalization-container.lite.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 97ac7b22f93..e6bea242408 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -43,11 +43,6 @@ export default function PersonalizationContainer(
From 3d107ca45f24b4c23b69ec900d5c27e257c8ccf7 Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 15:43:30 +0530 Subject: [PATCH 11/15] remove --- packages/react/src/blocks/PersonalizationContainer.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/react/src/blocks/PersonalizationContainer.tsx b/packages/react/src/blocks/PersonalizationContainer.tsx index 82bd771467e..106c93fea64 100644 --- a/packages/react/src/blocks/PersonalizationContainer.tsx +++ b/packages/react/src/blocks/PersonalizationContainer.tsx @@ -144,16 +144,6 @@ export function PersonalizationContainer(props: PersonalizationContainerProps) { ); }); - console.log( - 'here', - Builder.isBrowser, - Builder.isEditing, - Builder.isServer, - props.previewingIndex, - filteredVariants.length, - isClient - ); - return (
Date: Mon, 20 Jan 2025 16:07:14 +0530 Subject: [PATCH 12/15] saf --- .../personalization-container.lite.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index e6bea242408..db3238520de 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -3,6 +3,7 @@ import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; +import { isEditing } from '../../functions/is-editing.js'; import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; import { getPersonalizationScript } from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; @@ -79,8 +80,10 @@ export default function PersonalizationContainer( Date: Mon, 20 Jan 2025 16:09:45 +0530 Subject: [PATCH 13/15] remove --- packages/react/src/blocks/PersonalizationContainer.tsx | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/react/src/blocks/PersonalizationContainer.tsx b/packages/react/src/blocks/PersonalizationContainer.tsx index 106c93fea64..5ed2fb992c1 100644 --- a/packages/react/src/blocks/PersonalizationContainer.tsx +++ b/packages/react/src/blocks/PersonalizationContainer.tsx @@ -298,14 +298,6 @@ function getPersonalizationScript( var parentNode = winningVariant.parentNode; var newParent = parentNode.cloneNode(false); newParent.appendChild(winningVariant.content.firstChild); - console.log('newParent', { - parentNode: parentNode, - newParent: newParent, - winningVariant: winningVariant, - firstChild: winningVariant.content.firstChild, - lastChild: winningVariant.content.lastChild, - content: winningVariant.content, - }); parentNode.parentNode.replaceChild(newParent, parentNode); if (isDebug) { console.debug('PersonalizationContainer', 'Winning variant Replaced:', winningVariant); From bbed63809b35c4350abc9f5adc965dce2a843062 Mon Sep 17 00:00:00 2001 From: sidmohanty11 Date: Mon, 20 Jan 2025 17:02:23 +0530 Subject: [PATCH 14/15] fix --- .../personalization-container.lite.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index db3238520de..32031cabab6 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,4 +1,4 @@ -import { For, Fragment, Show, useStore } from '@builder.io/mitosis'; +import { For, Fragment, onMount, Show, useStore } from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; @@ -12,6 +12,7 @@ export default function PersonalizationContainer( props: PersonalizationContainerProps ) { const state = useStore({ + isHydrated: false, get filteredVariants() { return (props.variants || []).filter((variant) => { return filterWithCustomTargeting( @@ -40,6 +41,10 @@ export default function PersonalizationContainer( }, }); + onMount(() => { + state.isHydrated = true; + }); + return (
Date: Mon, 20 Jan 2025 19:47:12 +0530 Subject: [PATCH 15/15] fix --- .../personalization-container.spec.ts | 4 +- .../personalization-container/helpers.ts | 27 +++++++++++-- .../personalization-container.lite.tsx | 40 ++++++++++++++----- 3 files changed, 55 insertions(+), 16 deletions(-) diff --git a/packages/sdks-tests/src/e2e-tests/personalization-container.spec.ts b/packages/sdks-tests/src/e2e-tests/personalization-container.spec.ts index cbe77ba9a89..ec88fa0b667 100644 --- a/packages/sdks-tests/src/e2e-tests/personalization-container.spec.ts +++ b/packages/sdks-tests/src/e2e-tests/personalization-container.spec.ts @@ -1,6 +1,6 @@ import type { Browser } from '@playwright/test'; import { expect } from '@playwright/test'; -import { excludeGen2, test } from '../helpers/index.js'; +import { test } from '../helpers/index.js'; const SELECTOR = 'div[builder-content-id]'; const createContextWithCookies = async ({ @@ -35,7 +35,6 @@ const initializeUserAttributes = async ( page: _page, baseURL, browser, - sdk, packageName, }: Pick< Parameters[2]>[0], @@ -47,7 +46,6 @@ const initializeUserAttributes = async ( test.skip(packageName === 'gen1-next14-pages'); // gen1-remix started failing on this test for an unknown reason. test.skip(packageName === 'gen1-remix'); - test.skip(excludeGen2(sdk)); if (!baseURL) throw new Error('Missing baseURL'); diff --git a/packages/sdks/src/blocks/personalization-container/helpers.ts b/packages/sdks/src/blocks/personalization-container/helpers.ts index 21ed0b7b8d0..925b850123a 100644 --- a/packages/sdks/src/blocks/personalization-container/helpers.ts +++ b/packages/sdks/src/blocks/personalization-container/helpers.ts @@ -1,6 +1,27 @@ -import { filterWithCustomTargetingScript } from '../../functions/filter-with-custom-targeting'; -import { USER_ATTRIBUTES_COOKIE_NAME } from '../../helpers/user-attributes'; -import type { PersonalizationContainerProps } from './personalization-container.types'; +import { TARGET } from '../../constants/target.js'; +import { filterWithCustomTargetingScript } from '../../functions/filter-with-custom-targeting.js'; +import { isBrowser } from '../../functions/is-browser.js'; +import { USER_ATTRIBUTES_COOKIE_NAME } from '../../helpers/user-attributes.js'; +import type { PersonalizationContainerProps } from './personalization-container.types.js'; + +export function checkShouldRenderVariants( + variants: PersonalizationContainerProps['variants'], + canTrack: boolean +) { + const hasVariants = variants && variants.length > 0; + + if (TARGET === 'reactNative') return false; + + if (!hasVariants) return false; + if (!canTrack) return false; + + if (TARGET === 'vue' || TARGET === 'svelte') return true; + + if (isBrowser()) return false; + + return true; +} + export function getPersonalizationScript( variants: PersonalizationContainerProps['variants'], blockId: string, diff --git a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx index 32031cabab6..ba49c3120b3 100644 --- a/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx +++ b/packages/sdks/src/blocks/personalization-container/personalization-container.lite.tsx @@ -1,17 +1,43 @@ -import { For, Fragment, onMount, Show, useStore } from '@builder.io/mitosis'; +import { + For, + Fragment, + onMount, + Show, + useMetadata, + useStore, +} from '@builder.io/mitosis'; import Blocks from '../../components/blocks/blocks.lite.jsx'; import InlinedScript from '../../components/inlined-script.lite.jsx'; import InlinedStyles from '../../components/inlined-styles.lite.jsx'; import { filterWithCustomTargeting } from '../../functions/filter-with-custom-targeting.js'; import { isEditing } from '../../functions/is-editing.js'; +import { getDefaultCanTrack } from '../../helpers/canTrack.js'; import { userAttributesSubscriber } from '../../helpers/user-attributes.js'; -import { getPersonalizationScript } from './helpers.js'; +import { + checkShouldRenderVariants, + getPersonalizationScript, +} from './helpers.js'; import type { PersonalizationContainerProps } from './personalization-container.types.js'; +useMetadata({ + rsc: { + componentType: 'client', + }, +}); + export default function PersonalizationContainer( props: PersonalizationContainerProps ) { const state = useStore({ + scriptStr: getPersonalizationScript( + props.variants, + props.builderBlock?.id || 'none', + props.builderContext.value?.rootState?.locale as string | undefined + ), + shouldRenderVariants: checkShouldRenderVariants( + props.variants, + getDefaultCanTrack(props.builderContext.value?.canTrack) + ), isHydrated: false, get filteredVariants() { return (props.variants || []).filter((variant) => { @@ -51,7 +77,7 @@ export default function PersonalizationContainer( {...props.attributes} class={`builder-personalization-container ${props.attributes?.class || ''}`} > - + {(variant, index) => (