Hi!
Great questions. I can go ahead and take a loom video for you today for that first approach/ workaround if that’s helpful in terms of how I built this out and walk you through the steps.
1. Default page + specific page for certain customers
Yes! Instead of returning a 404 for non matching customers, you can publish two pages in Builder with the same URL, one default (leave allowedCustomers empty) and one targeted (fill in the customer numbers). Then in your code, fetch all pages for that URL and pick the right one:
const allContent = await builder.getAll('page', {
userAttributes: { urlPath: '/your-page-path' },
limit: 20,
});
// Find the page specifically targeting this customer
const specificPage = allContent.find((page) => {
const allowed = page.data?.allowedCustomers as string;
if (!allowed) return false;
return allowed.split(',').map((n) => n.trim()).includes(customerNumber);
});
// Fall back to the default page if no specific match
const defaultPage = allContent.find((page) => !page.data?.allowedCustomers);
const content = specificPage ?? defaultPage ?? null;
Note that we intentionally don’t pass customerNumber to Builder’s API here because Builder does exact string matching server side, so it can’t match a single customer number against a comma separated list. So we fetch all pages for that URL and handle the matching ourselves in code.
So customers with a matching number see the targeted page, everyone else sees the default so no error page will be needed.
2. Variant Container (Personalize)
The Personalize container works differently from the page level approach. Instead of server-side API filtering, it uses builder.setUserAttributes() which stores attributes in a cookie and does the matching on the client side. This means Builder’s exact string matching works fine here and we don’t need the comma separated workaround.
To set it up, call setUserAttributes at the global level in a "use client" component, before React renders:
"use client"
import { builder } from "@builder.io/sdk";
// Must be outside the component at the global context
builder.setUserAttributes({ customerNumber: "1042" });
export default function MyPage() {
return <BuilderComponent content={content} model={model} />;
}
Then in the Personalize container in the editor, set Variant 2’s targeting rule to customerNumber is 1042.
This works well if each variant targets a single customer number or a small fixed set.
However, if you need to target a large chunk of customer numbers per variant, the Personalize container isn’t the right fit, the page level allowedCustomers approach from my previous reply would be the better solution in that case.
Hope that helps. Let me know if you have any other questions!