Blog

3 min read

Audience traits: personalization that respects the visitor

Tell Badgerlytics what an anonymous visitor is (plan, signed-in, tenure) without who they are. Then target experiments and feature flags on it.

Personalization has a reputation problem. It usually means "we know your name and we're going to use it." Audience traits are the other kind: you tell us what a visitor is — on the pro plan, signed in, a returning shopper — never who they are.

Traits, then segments

  • A trait is a fact about an anonymous visitor: signed_in: true, plan: 'pro', account_age_days: 124.
  • An audience segment is a rule over traits: "signed-in pro users on mobile."

Traits are set from your code. Segments are built in the dashboard, on the flag or experiment they apply to. Neither requires an email address.

Built in vs registered

Some traits exist automatically and need no setup:

Built-inValues
visitor_typenew, returning
device_typedesktop, mobile, tablet
page_paththe current path
utm_source, utm_medium, utm_campaignfrom the landing URL

Everything else is a custom trait you register once under Events / Funnel / Audience setup → Audience: pick a label and a type (boolean, string, number) and we generate the token — "Logged in" becomes logged_in.

Setting traits from your app

Update traits whenever state changes — login, logout, plan upgrade:

// On login
window.badgerlytics.setTraits({
signed_in: true,
plan: 'pro',
account_age_days: 124,
});
// On logout
window.badgerlytics.setTraits({
signed_in: false,
plan: null,
});

Server-rendered apps should also set the _bai_traits cookie on login so segment rules apply on the very first render — setTraitsOnResponse for Next.js, Remix, and Astro, setTraitsOnEvent for Nuxt. See SSR middleware.

Keep PII out. Names, emails, and phone numbers don't belong in traits. plan and tenure_bucket do.

Building a segment rule

On any flag or experiment, Audience segment starts as All visitors. Switch to Custom segment and add conditions on built-in or custom traits — signed_in equals true, plan equals pro, device_type is mobile, utm_campaign equals spring_sale — combined with AND or OR. Only visitors who match at assignment time are bucketed.

Two things to do with a segment

1. Target an experiment. Restrict bucketing to a slice — run the pricing test on free-tier users only. That's a big enough topic for its own post.

2. Personalize with a flag. Show the annual-plan nudge to trialing users. Hide the "create account" banner from people who have one. Two ways to do it:

  • Branch in code on the traits you already set.
  • Create a Feature flag (on/off) with a custom segment and check isFlagEnabled() — you get a kill switch and a rollout weight for free.

Want location in the mix? Read it from getLocation() and store the bit you care about as a trait — setTraits({ country: loc.country }) — then target on it. Details in Geolocation.

SaaS teams: subscription state is your best trait

The segments that pay off most in SaaS are usually trialing, active, past_due. Set the trait when the state changes and every experiment or rollout can be scoped to it.

Housekeeping

  • Copy traits across properties with Copy to property… to keep stage and production in sync. It's create-only — no overwrites.
  • Name traits for humans. "Signed in" ages better than "flag_3."
  • Register traits on the destination property before copying a flag whose rules reference them.

Docs: Audiences and How-to: Create an audience trait. If you're comparing this to a dedicated personalization tool, the trade-off is simple: less black-box targeting, more control over exactly what you know about a visitor.

Quick answers

What is an audience trait in Badgerlytics?
A key/value attribute you set on an anonymous visitor — like signed_in, plan, or account_age_days — using setTraits() in the browser or a cookie on the server. Traits feed the audience segment rules that decide which visitors are bucketed into an experiment or feature flag.
Which traits are built in?
visitor_type (new or returning), device_type, page_path, and utm_source, utm_medium, and utm_campaign are always available. Custom traits (boolean, string, or number) are registered once under Events / Funnel / Audience setup → Audience.
Can I personalize content with audiences without running an A/B test?
Yes. Create a Feature flag (on/off) with a custom audience segment and check isFlagEnabled() in your code, or branch directly on the traits you already set.

Ready to see what your data has been hiding?

Join the teams using Badgerlytics to grow revenue, run smarter experiments, and finally understand their funnels.

Cancel anytime.