Key takeaways
- A tailored website changes parts of a page based on signals you can explain.
- Start with campaign and language matching; move to behaviour and profiles only when the earlier levels have proved their worth.
- Decide on the server or at the edge, cache each variant safely and always keep a working default.
- Ask before remembering behaviour, avoid sensitive inferences and let people switch personalisation off.
- Keep a control group, and remove any rule that doesn’t measurably help.
A website that shows every visitor the same page treats a first-time visitor from a paid campaign, a returning customer and someone browsing from another country as if they wanted the same thing. A tailored website closes some of that gap. Done well, it feels like the site simply understood what you came for. Done badly, it feels like being followed around a shop.
This guide is about doing it well. It sets out four levels of personalisation, from the simple and safe to the complex, what each one needs technically, how to handle consent, how to test whether it actually helps, and when it isn’t worth building at all.
What is a tailored website?
A tailored website is one that changes parts of what a visitor sees, such as the headline, the examples, the order of content or the call to action, based on what it knows about that visitor. The rest of the page stays the same. The aim is relevance: tailoring a digital platform to user needs so each visitor reaches what they came for with fewer clicks.
Personalisation is different from customisation. Personalisation is the site choosing for the visitor (“you came from the freelancer campaign, so here is invoicing”). Customisation is the visitor choosing for themselves (setting a language, saving a dashboard layout, picking which updates to see). Good tailored websites use both, and customisation is often the better starting point because the visitor is in control.
The four levels of website personalisation
Each level uses a different signal, needs more data and more engineering than the one before, and carries more risk of feeling intrusive. Most sites should start at level one and move up only when the previous level has proved its worth.
Each level in more detail:
Level 1: by campaign or source
Match the page to the link the visitor clicked. If an ad or email talks about invoicing for freelancers, the landing page should say the same thing in its headline and examples, not show the generic home page. The signal is the campaign tag in the link (such as utm_campaign) or the referring site.
This is the cheapest and safest level. It uses no personal data, needs no stored history and is easy to test, because each campaign already has its own traffic. Most of what people call landing page optimisation is personalisation at this level, which is why landing page testing for paid campaigns usually starts here.
Level 2: by location and language
Show the right language, currency, delivery information, phone number and examples for where the visitor is. The signals are the language their browser asks for (the Accept-Language header) and the country your CDN or hosting platform detects from their IP address.
Two rules keep this level from going wrong:
- Suggest, don’t force. Offer a switch to the detected language or country and remember the choice. Automatically redirecting people traps travellers, expats and anyone on a VPN in the wrong version.
- Give each language its own URL (such as
/fr/or a separate domain) rather than changing the language on one URL, so search engines can index every version and people can share the right link.
Level 3: by behaviour on the site
Change what you show based on what the visitor has done: the pages they read, the product category they browsed, whether they started a sign-up and stopped. A returning visitor who read three articles about one topic might see that topic first; someone who abandoned a form might see a shorter version of it.
This level needs a record of behaviour across visits, usually a first-party cookie linked to your own analytics events, and that means consent in many places. It also needs enough traffic for each behaviour group to be worth designing for. Many sites find that a few well-chosen rules (“returning visitor”, “viewed pricing”) capture most of the value.
Level 4: by account or profile
Once visitors sign in, you know what they told you and what they use: their role, plan, industry, the features they have tried. Logged-in personalisation can be deep: an onboarding checklist that skips what they’ve done, a home screen built around their role, help articles for the features they actually use.
This is where personalisation becomes part of the product rather than the marketing site, and it is built into the web app itself. It is also where people expect it most: a logged-in customer is usually happy for the product to remember them.
Planning personalisation?
We’d start with one high-traffic page, one goal and two or three visitor groups, with a control group from day one. Tell us about your site.
What each level needs technically
Each level reads different signals, makes its decision in a different place and stores different data:
The building blocks are:
- Rules. Readable “if this, show that” rules cover most needs. They are easy to explain, test and switch off. Machine learning recommendations make sense only with large catalogues and a lot of traffic.
- Content variants. Each personalised slot (the hero, a block of examples, a call to action) needs its variants written and stored, usually as fields in your CMS, with a default that always works.
- A place to make the decision. Deciding on the server or at the edge, before the page is sent, avoids the flicker of a page that changes after it loads, and keeps the page fast. Deciding in the browser is simpler to add to an existing site but often causes that flicker.
- Caching that knows about variants. A cached page must not show one visitor’s version to another. Cache each variant separately (for example, by varying the cache on language or a variant cookie), or cache the page and fill only the personalised slot per request.
- Measurement. Every personalised view should be logged with the variant shown, so you can compare outcomes later.
A simple rules engine
Here is a small, dependency-free example in JavaScript that picks a hero block for each visitor. It reads three signals from a request (a campaign tag, a country header from the CDN and two cookies) and applies rules in order. Save it as personalise.mjs and run it with Node.js 18 or later:
// personalise.mjs: pick the hero block for a visitor from simple rules
// Runs on Node.js 18 or later, with no dependencies: node personalise.mjs
import { pathToFileURL } from 'node:url';
const HEROES = {
default: { heading: 'Accounting software for growing teams', cta: 'Start a free trial' },
'campaign:freelancers': { heading: 'Invoicing made simple for freelancers', cta: 'Send your first invoice' },
'country:GB': { heading: 'Accounting software, priced in pounds', cta: 'See UK plans' },
returning: { heading: 'Welcome back', cta: 'Pick up where you left off' },
};
// Rules run top to bottom and the first match wins. Each reads one signal you can explain.
const RULES = [
{ id: 'campaign:freelancers', when: (v) => v.utmCampaign === 'freelancers' },
{ id: 'returning', when: (v) => v.consented && v.visits > 1 },
{ id: 'country:GB', when: (v) => v.country === 'GB' },
];
export function pickHero(visitor) {
const rule = RULES.find((r) => r.when(visitor));
const id = rule ? rule.id : 'default';
return { id, ...HEROES[id] };
}
// Read the signals from a request. Anything missing falls back to the default.
export function visitorFrom(url, headers = {}, cookies = {}) {
const params = new URL(url).searchParams;
return {
utmCampaign: params.get('utm_campaign'),
country: headers['x-country'] ?? null, // set by your CDN or edge platform; the header name varies
consented: cookies.consent === 'yes',
visits: Number.parseInt(cookies.visits ?? '0', 10) || 0,
};
}
// Run this file directly to check the rules against four sample visitors.
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
const samples = [
['https://example.com/?utm_campaign=freelancers', {}, {}],
['https://example.com/', { 'x-country': 'GB' }, {}],
['https://example.com/', { 'x-country': 'GB' }, { consent: 'yes', visits: '3' }],
['https://example.com/', {}, { consent: 'no', visits: '3' }],
];
for (const [url, headers, cookies] of samples) {
console.log(pickHero(visitorFrom(url, headers, cookies)).id);
}
}
Running it prints campaign:freelancers, country:GB, returning and default, one per sample visitor. Notice the last one: the visitor has been before, but hasn’t consented, so the behaviour rule doesn’t apply and they see the default. In a real site, pickHero would run in your server or edge function before the page is rendered, and the header name for the visitor’s country depends on your CDN or hosting platform.
Consent and privacy: personalise without being creepy
The line between helpful and creepy is usually whether the visitor can see why the site is showing them something. “Because you’re in the UK” and “because you came from our freelancer email” feel fine. “Because we noticed you looked at this three times last week” can feel like surveillance, even when it is technically allowed.
Practical rules that keep personalisation on the right side of that line:
- Ask before you remember. Behaviour-based personalisation that stores a visitor ID belongs behind the visitor’s consent choice, and the site must still work well without it.
- Personalise on what visitors would expect you to know, such as the campaign they clicked, their language, their account settings, not on inferences about health, finances, religion or other sensitive traits.
- Explain and let people switch off. A short note (“Showing UK pricing. Change”) and a setting to turn personalisation off build trust.
- Keep data to what changes the page. If a field never changes what you show, don’t collect it for personalisation.
- Never personalise the price of the same product for different people without a clear, stated reason such as a regional price list. It is the fastest way to lose trust.
Privacy laws, such as the EU’s GDPR and India’s DPDP Act, set rules on personal data and consent that vary by country, so check how they apply to your audience with someone qualified before you launch behaviour-based personalisation. Consent choices and personalisation settings work best when they are part of the UI UX design from the start, rather than a banner added at the end.
How to test whether personalisation helps
Run a controlled test: personalisation adds content to maintain, so prove it earns its place.
- Pick one goal per experiment, such as sign-ups, demo requests or a key product action. Not “engagement”.
- Keep a control group. Show a random share of eligible visitors the default version, even when a rule matches them. Without a control group, you can’t tell whether a personalised visitor converted because of the personalisation or because they were already more likely to.
- Decide the sample size before you start, using a sample size calculator, and don’t stop the test early because one version is ahead.
- Compare the personalised group with its control, not with the whole site.
- Keep the variants that win and remove the rest. A rule that doesn’t help is content someone has to keep updating for nothing.
If your traffic is too small for a fair test, prefer the levels that are obviously right (matching the campaign, showing the right language) and spend the effort on a clearer single page. Our guide to a conversion-focused website covers that side.
When isn’t website personalisation worth it?
Website personalisation isn’t worth it when the site has too little traffic to measure the effect, when there is no team to write and maintain the variants, or when the default page isn’t clear yet. Personalising an unclear page gives you several unclear pages.
Before you build, check whether the site is ready and whether you can test it fairly. Tick what is true for your site:
Examples of personalisation by industry
The same four levels look different by sector:
Whatever the sector, the data behind the rules matters as much as the rules. Our guide to data-driven targeted marketing covers collecting first-party data that makes these rules possible.
How we’d approach building it
We’d start by choosing one high-traffic page and one goal, then write down the two or three visitor groups whose needs on that page clearly differ. For each group we’d agree the rule, the variant and the default, and build the decision on the server or at the edge so the page stays fast and doesn’t flicker. Logging every variant shown comes before launch, a control group from day one, and a review after the agreed sample size to keep or remove each rule. Personalisation in a logged-in product is part of custom web app development, built into the application’s own screens and data.
