@builder.io/personalization-utils
TypeScript icon, indicating that this package has built-in type declarations

4.0.0 • Public • Published

Builder Personalization Utils

A collection of handy utilities when working with delivering personalized Builder content at the edge.

npm install @builder.io/personalization-utils

How to start with personalized rewrites?

This utility library helps you encode/decode targeting attributes as parts of the URL to allow for caching (or statically generating) render results, it should be used in middleware in combination with a page path handler (for e.g a catch all page pages/[[...path]].jsx):

import { parsePersonalizedURL } from '@builder.io/personalization-utils/next'
// in pages/[[...path]].jsx
export async function getStaticProps({ params }) {
  const { attributes } = parsePersonalizedURL(params?.path);
  const page =
    (await builder
      .get('page', {
        apiKey: builderConfig.apiKey,
        userAttributes: attributes,
        // cachebust is not advised outside static rendering contexts.
        cachebust: true,
      })
      .promise()) || null

  return {
    props: {
      page,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 1 second
    revalidate: 1,
  }
}

export function getStaticPaths() {
  return {
    paths: [],
    fallback: true,
  }
}

export default function Path({ page }) {
  return  <BuilderComponent model="page" content={page} />
}

Now that we have a path for rendering builder content ready, let's route to it in the middleware:

import { getPersonalizedURL } from '@builder.io/personalization-utils/next'

const excludededPrefixes = ['/favicon', '/api'];

export default function middleware(request) {
  const url = request.nextUrl
  if (shouldRewrite(url.pathname)) {
    const personalizedURL = getPersonalizedURL(request)
    return NextResponse.rewrite(personalizedURL)
  }
  return NextResponse.next();
}
const audience = await myCDP.identifyAudience(userID);
// this will include the `audience` in all api calls and save it in a cookie `builder.userAttributes`
builder.setUserAttributes({ audience })

Once the cookie is set, all builder content matching from now on will weigh in the current audience segment.

Using trimHtml for Dynamic Containers and A/B Tests

The trimHtml function is a utility for handling dynamic personalization containers and A/B test variants in your HTML content. It's particularly useful for processing personalized content at the edge or in server-side rendering scenarios.

Usage

import { trimHtml } from '@builder.io/personalization-utils'

const fullHTML = '... your full HTML string with personalization containers and A/B test variants ...';
const userAttributes = {
  audience: 'segment-a',
  date: '2023-06-15T12:00:00Z'
};
const abTests = {
  'content-id-1': 'variant-a',
  'content-id-2': 'variant-b'
};

const { html } = trimHtml(fullHTML, { userAttributes, abTests });

To get the userAttributes, you should parse the builder.userAttributes cookie. Here's an example of how you might do this:

import { parse } from 'cookie'

function getUserAttributes(req) {
  const cookies = parse(req.headers.cookie || '');
  const builderAttributes = cookies['builder.userAttributes'];
  return builderAttributes ? JSON.parse(builderAttributes) : {};
}

// Then in your request handler:
const userAttributes = getUserAttributes(req);

To get the abTests data, you can parse the relevant cookies like this:

import { parse } from 'cookie'

function getAbTests(req) {
  const cookies = parse(req.headers.cookie || '');
  const abTests = Object.entries(cookies).reduce((acc, [cookieName, cookieValue]) => {
    if (cookieName.startsWith('builder.tests')) {
      return {
        ...acc,
        [cookieName.split('.').slice(-1)[0]]: cookieValue
      }
    }
    return acc;
  }, {});
  return abTests;
}

// Then in your request handler:
const abTests = getAbTests(req);
const { html } = trimHtml(fullHTML, { userAttributes, abTests });

The trimHtml function processes the HTML in the following order:

  1. It first applies A/B test variants based on the provided abTests object.
  2. Then it evaluates personalization containers against the provided user attributes.
  3. Finally, it returns a new HTML string with the appropriate personalized content and A/B test variants.

This approach allows you to deliver personalized content and A/B test variants while still leveraging edge caching or static site generation, as the personalization and A/B test logic is applied after the initial HTML is generated.

Readme

Keywords

none

Package Sidebar

Install

npm i @builder.io/personalization-utils

Weekly Downloads

222

Version

4.0.0

License

none

Unpacked Size

43.7 kB

Total Files

16

Last publish

Collaborators

  • steve8708
  • samijaber
  • teleaziz123
  • mrkoreye
  • strd6
  • mhevery
  • adamdbradley
  • gustavohgs
  • manucorporat
  • shyam-builder
  • sanyamkamat
  • harmeet.builder
  • midhunadarvin
  • kylefowler
  • builderio-bot
  • armela
  • anaghavarhade
  • sidmohanty11
  • yash-wadhia-builder
  • paprikaf
  • clyde-builderio