Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { expect } from '@playwright/test';
import { test } from '../helpers/index.js';

test.describe('TargetedPageSetAttributes Component', () => {
test.beforeEach(async ({ context, packageName }) => {
test.skip(!['gen1-react', 'react'].includes(packageName));
await context.clearCookies();
const page = await context.newPage();
await page.goto('/targeted-page-set-attributes');
});

test('should render the No Targets page if there is no targeting', async ({ page }) => {
await page.goto('/targeted-page-set-attributes');
expect(await page.locator('h2').innerText()).toContain('No Targets');
});

test('should render the Recent Shopper page when attributes are set', async ({ page }) => {
await page.goto('/targeted-page-set-attributes?target=set-attributes');
expect(await page.locator('h2').innerText()).toContain('Recent Shopper');
});
});
41 changes: 41 additions & 0 deletions packages/sdks-tests/src/snippet-tests/targeted-page.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect } from '@playwright/test';
import { test } from '../helpers/index.js';

test.describe('TargetedPage Component', () => {
test.beforeEach(async ({ page, packageName }) => {
test.skip(!['gen1-react', 'react'].includes(packageName));
await page.goto('/targeted-page');
});

test('should render the Desktop page if there is no targeting', async ({ page }) => {
await page.goto('/targeted-page');
expect(await page.locator('h2').innerText()).toContain('Desktop');
});

test('should render the Desktop page with appropriate targeting', async ({ page }) => {
await page.goto('/targeted-page?target=desktop');
expect(await page.locator('h2').innerText()).toContain('Desktop');
});

test('should render the Mobile page with appropriate targeting', async ({ page }) => {
await page.goto('/targeted-page?target=mobile');
expect(await page.locator('h2').innerText()).toContain('Mobile');
});

test("should render the Men's Fashion page with appropriate targeting", async ({ page }) => {
await page.goto('/targeted-page?target=mens-fashion');
expect(await page.locator('h2').innerText()).toContain("Men's Fashion");
});

test('should render the Recent Shopper page with appropriate targeting included in array', async ({
page,
}) => {
await page.goto('/targeted-page?target=multi-target');
expect(await page.locator('h2').innerText()).toContain('Recent Shopper');
});

test('should render the Logged In page with appropriate boolean targeting', async ({ page }) => {
await page.goto('/targeted-page?target=is-logged-in');
expect(await page.locator('h2').innerText()).toContain('Logged');
});
});
10 changes: 10 additions & 0 deletions packages/sdks/snippets/gen1-react/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import CustomChild from './routes/custom-child';
import EditableRegion from './routes/editable-region';
import IntegratingPages from './routes/IntegratingPages';
import QueryCheatsheet from './routes/query-cheatsheet';
import TargetedPage from './routes/targeted-page';
import TargetedPageSetAttributes from './routes/targeted-page/set-attributes';

const router = createBrowserRouter([
{
Expand All @@ -29,6 +31,14 @@ const router = createBrowserRouter([
path: '/query-cheatsheet',
element: <QueryCheatsheet />,
},
{
path: '/targeted-page',
element: <TargetedPage />,
},
{
path: '/targeted-page-set-attributes',
element: <TargetedPageSetAttributes />,
},
{
path: '/*',
element: <IntegratingPages />,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { builder } from '@builder.io/react';
import type { GetContentOptions } from '@builder.io/sdk';

export default function targetedRequest(
modelName: string,
options: GetContentOptions
) {
return builder.get(modelName, {
userAttributes: {
audience: ['recent-shopper', 'womens-fashion'],
},
...options,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { builder } from '@builder.io/react';
import type { GetContentOptions } from '@builder.io/sdk';

export default function targetedRequest(
modelName: string,
options: GetContentOptions
) {
return builder.get(modelName, {
userAttributes: {
audience: ['mens-fashion'],
},
...options,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { builder } from '@builder.io/react';
import type { GetContentOptions } from '@builder.io/sdk';

export default function targetedRequest(
modelName: string,
options: GetContentOptions
) {
return builder.get(modelName, {
userAttributes: {
device: 'desktop',
},
...options,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { BuilderComponent, builder, useIsPreviewing } from '@builder.io/react';
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import FourOhFour from '../../components/404';

import customTargetingMultiRequest from './custom-targeting-multi-request';
import customTargetingRequest from './custom-targeting-request';
import desktopRequest from './desktop-request';
import loggedInRequest from './is-logged-in-request';
import mobileRequest from './mobile-request';
import noTargetRequest from './no-target-request';

const MODEL = 'targeted-page';
builder.init('ee9f13b4981e489a9a1209887695ef2b');

export default function TargetedPage() {
const isPreviewingInBuilder = useIsPreviewing();
const [notFound, setNotFound] = useState(false);
const [content, setContent] = useState();
const [searchParams] = useSearchParams();

const fnMap: { [key: string]: any } = {
desktop: desktopRequest,
mobile: mobileRequest,
'mens-fashion': customTargetingRequest,
'multi-target': customTargetingMultiRequest,
'is-logged-in': loggedInRequest,
};

useEffect(() => {
async function fetchContent() {
const target: string = searchParams.get('target') || '';
const targetFn = target ? fnMap[target] : noTargetRequest;

const content = await targetFn(MODEL, {
url: window.location.pathname,
});

setContent(content);
setNotFound(!content);

if (content?.data.title) {
document.title = content.data.title;
}
}
fetchContent();
}, [window.location.pathname]);

if (notFound && !isPreviewingInBuilder) {
return <FourOhFour />;
}

console.log('...', builder.getUserAttributes());

return (
<>
<h1>Targeting Snippet</h1>
<hr />
<BuilderComponent model={MODEL} content={content} />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { builder } from '@builder.io/react';
import type { GetContentOptions } from '@builder.io/sdk';

export default function targetedRequest(
modelName: string,
options: GetContentOptions
) {
return builder.get(modelName, {
userAttributes: {
isLoggedIn: true,
},
...options,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { builder } from '@builder.io/react';
import type { GetContentOptions } from '@builder.io/sdk';

export default function targetedRequest(
modelName: string,
options: GetContentOptions
) {
return builder.get(modelName, {
userAttributes: {
device: 'mobile',
},
...options,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { builder } from '@builder.io/react';
import type { GetContentOptions } from '@builder.io/sdk';

export default function targetedRequest(
modelName: string,
options: GetContentOptions
) {
return builder.get(modelName, {
...options,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { BuilderComponent, builder, useIsPreviewing } from '@builder.io/react';
import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import FourOhFour from '../../components/404';
import setTargetingAttributes from './setUserAttributes';

const MODEL = 'targeted-page';
builder.init('ee9f13b4981e489a9a1209887695ef2b');

export default function TargetedPageSetAttributes() {
const isPreviewingInBuilder = useIsPreviewing();
const [notFound, setNotFound] = useState(false);
const [content, setContent] = useState();
const [searchParams] = useSearchParams();

useEffect(() => {
async function fetchContent() {
const target: string = searchParams.get('target') || '';

if (target === 'set-attributes') {
setTargetingAttributes();
}

const content = await builder.get(MODEL, {
url: window.location.pathname,
});

setContent(content);
setNotFound(!content);

if (content?.data.title) {
document.title = content.data.title;
}
}
fetchContent();
}, []);

if (notFound && !isPreviewingInBuilder) {
return <FourOhFour />;
}

return (
<>
<h1>Targeting Snippet : Set Attributes</h1>
<hr />
<BuilderComponent model={MODEL} content={content} />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { builder } from '@builder.io/react';

export default function setTargetingAttributes() {
builder.setUserAttributes({
device: 'desktop',
audience: ['recent-shopper', 'womens-fashion'],
});
}
15 changes: 14 additions & 1 deletion packages/sdks/snippets/react/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import EditableRegionRoute from './routes/custom-components/editable-region.tsx'
import IntegratingPages from './routes/IntegratingPages.tsx';
import LivePreviewBlogData from './routes/LivePreviewBlogData.js';
import QueryCheatsheet from './routes/query-cheatsheet/index.tsx';
import TargetedPage from './routes/targeted-page/index.tsx';
import TargetedPageSetAttributes from './routes/targeted-page/set-attributes.tsx';

const router = createBrowserRouter([
{
Expand Down Expand Up @@ -55,7 +57,18 @@ const router = createBrowserRouter([
path: '/marketing-event',
element: <Hero />,
},
{ path: '/home', element: <Homepage /> },
{
path: '/targeted-page',
element: <TargetedPage />,
},
{
path: '/targeted-page-set-attributes',
element: <TargetedPageSetAttributes />,
},
{
path: '/home',
element: <Homepage />,
},
{
path: '/*',
element: <IntegratingPages />,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { fetchOneEntry, GetContentOptions } from '@builder.io/sdk-react';

export default function targetedRequest(options: GetContentOptions) {
return fetchOneEntry({
...options,
userAttributes: {
audience: ['recent-shopper', 'womens-fashion'],
...options.userAttributes,
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { fetchOneEntry, GetContentOptions } from '@builder.io/sdk-react';

export default function targetedRequest(options: GetContentOptions) {
return fetchOneEntry({
...options,
userAttributes: {
audience: ['mens-fashion'],
...options.userAttributes,
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { fetchOneEntry, GetContentOptions } from '@builder.io/sdk-react';

export default function targetedRequest(options: GetContentOptions) {
return fetchOneEntry({
...options,
userAttributes: {
device: 'desktop',
...options.userAttributes,
},
});
}
Loading
Loading