Under the hood

How Spectare works

From the moment a visitor lands to the moment personalised content appears: intent classification, atom assembly, brand voice, multi-tier caching, image selection, and a presentation learning system that improves with every session.

Before any of this

Everything below runs on your atom library. Write atoms directly in the admin, or import them from an existing site: Spectare reads your published pages and drafts focused atoms for you to review, so personalisation starts from real content on day one, not a blank library. Nothing publishes without your approval.

Script tag

Client-side slots

spectare.js runs in the browser after page load. It reads UTM params, referrer, and localStorage, calls qualify, then assembles and fills data-spectare-slot divs. Works on any site that runs JavaScript. Visitors see a brief shimmer while the pipeline runs.

Browser → /api/qualify/your-org
Browser → /api/assemble/components
Browser → fills slot divs

WordPress plugin

Server-rendered zones

The PHP plugin calls /api/assemble/ssr on the server before the page is sent. Zone shortcodes or Gutenberg blocks mark where each content type renders: hero, body, proof, cta. Content is in the HTML at first paint. Page caching is bypassed automatically.

PHP → /api/assemble/ssr
Filters assembly by zone
HTML contains content at paint
No shimmer, no client JS required

Next.js SSR

React server components

Your server component reads signals from the HTTP request before the page is sent. It calls /api/assemble/ssr and passes the result to PersonalisedSection. Content is in the HTML at first paint with no shimmer. The client confirms intent and tracks conversions.

Server → /api/assemble/ssr
HTML contains content at paint
variantId seeded into sessionStorage
Client confirms + tracks conversions
01Intent classification

Reading the visitor

On the client-side path, spectare.js runs on every page load. It reads the referrer, UTM parameters, landing page URL, and any page visit history stored in localStorage from earlier in the session or from previous visits. These signals are sent to /api/qualify/your-org, where Claude classifies them into an audience, funnel stage, and confidence score. The result is a signed context token: not a user profile, not a cookie, not a segment. On the Next.js SSR path, signals come from the HTTP request headers and query string instead. The SSR qualify result is also cached by signal pattern for 7 days, and flushed the moment you change your audience segments or other settings, so repeat visitors with the same page, referrer, and UTM signature skip the Claude call entirely and receive a classification in under 50ms.

referrerUTM paramslanding page URLvisit history (localStorage)

spectare.js

collects signals and calls qualify

POST /api/qualify/your-org

sends context to the server

Claude: classify intent

audience · stage · confidence

Signed context token

carries audience, stage, and confidence. Valid for 1 hour.

spectare.js runs client-side on every page load

No training period

Claude is the model. Classification is accurate from visitor one without historical traffic data.

No cookies

Intent is classified fresh each session on the client-side path. On the SSR path, the classify result is cached by signal pattern, not by person. No visitor profile is ever stored.

Returning visitors

Visit history in localStorage means returning visitors are personalised even with no UTM params.

02Content assembly

Building the experience

On the client-side path, the context token is passed to /api/assemble/components. On the Next.js SSR path, /api/assemble/ssr handles qualify and assemble in a single server call with no token exchange needed. Either way, the core assembly logic runs: vector search, conversion history, and image selection in parallel, then Claude selecting from a registry of 9 component types. Claude sees which atoms have converted most for this audience and stage, and which atoms have appeared together in past converting sessions. Semantic similarity finds the candidates. Past performance decides between them. The result is a component list that renders in the browser (client path) or arrives pre-rendered in the HTML (SSR path).

Context token

audience · stage · confidence

Vector search

candidates by semantic similarity

Conversion history

atoms + arrangements that converted for this audience + stage

Image selection

best overlay image for audience + stage

Claude: assemble page

picks atoms, picks component types, writes Claude-owned slots in your brand voice

HeroStatement

Claude writes

ImageCtaHero

Claude writes

AtomCard

StatGrid

FeatureList

TestimonialCard

ComparisonTable

CodeBlock

CtaStrip

Rendered page

personalised content in the browser

Claude writes (uses your brand voice)Drawn from your atoms, unchanged

Runs on the server after qualify returns a token

What Claude writes

Claude generates fresh copy for two component types: HeroStatement (headline and subheading) and ImageCtaHero (headline, subheading, and CTA label). Everything else (AtomCard prose, StatGrid numbers, TestimonialCard quotes) is drawn directly from your atoms and never rewritten.

Brand voice

Set a plain-English instruction in Settings and Claude writes every headline in your voice: "Direct and confident. Short sentences. No jargon." Brand voice only applies to Claude-written components. Your atom content is never rewritten regardless of what you set.

03Delivery speed

Two-tier caching

Personalisation runs through two caches, checked in turn, so most visits never call Claude at all. The first reuses the visitor’s classification (signals to audience, stage, and intent); the second reuses the assembled page for that intent. Both are pre-warmed for common patterns and kept for seven days, so even a first visitor usually lands on a warm result and the page is served in about 200ms. The image bandit still runs on every request, even on a hit, so image optimisation never stalls.

1. Qualify cachewho is this visitor

Signals to intent

Hit: a visitor with the same signals was classified before, so the audience, stage, and intent are reused with no Claude call. Miss: Claude Haiku reads the signals once, then the result is cached.

hit: 0 Claude callsmiss: one Haiku call
2. Assembly cachewhat page they get

Intent to page

Hit: that intent (type, audience, stage) was assembled recently, so the personalised layout is served in about 200ms with no Claude call. Image selection still runs every time. Miss: Claude assembles the components once for that pattern, then writes it back so the next visitor hits the cache.

hit: ~200msmiss: assembled once

Two caches, checked in turn. Both are pre-warmed for common patterns and kept for 7 days, so most visits skip Claude entirely.

Zero-flicker delivery for Next.js

Next.js customers can call /api/assemble/ssr from a server component before the page is sent to the browser. The shared Redis cache means warm intent patterns return a pre-assembled component list in under 50ms. PersonalisedSection accepts the pre-rendered assembly as a prop: if the client classify result matches the server result, no DOM update occurs and the visitor sees no content flash at any network speed.

04Image selection

The image bandit

Spectare selects a hero image for each assembled experience. It uses a multi-armed bandit: 90% of requests exploit the image with the highest observed conversion rate for the current audience and stage combination; 10% explore a random image to gather data on untested combinations. Every impression is recorded, and conversions update the conversion rate in real time. No manual A/B test setup required.

Visitor arrives

audience + stage known from qualify

Select image

exploit (90%) or explore (10%)

Record impression

image, audience, and stage recorded

Visitor converts?

Conversion recorded

linked to this image, audience, and stage

Next visitor

image with the best conversion rate for this audience + stage

10% of requests explore a random image. 90% exploit the best-converting image.

05Feedback loop

The co-conversion graph

Every conversion event records which atoms appeared together in that session. A graph tracks how often every pair of atoms appears together in converting sessions. When the assembly pipeline picks a primary atom, it reads the graph to surface supporting atoms that have actually worked alongside that primary, not just ones that are semantically similar. Claude also receives the top-converting atom IDs for the visitor's specific audience and stage combination, drawn from the last 30 days of conversions. Both signals are passed directly to Claude during assembly, on every path: client-side, SSR, and script tag. The graph is rebuilt nightly from all conversion data.

Visitor converts

session contained atoms A, B, and C

Co-conversion links updated

every pair of atoms in the session gets a stronger link

Next visitor: primary = A

assembly reads the strongest co-conversion links for A

B

weight 12

C

weight 7

D

weight 2

B is chosen. Not just semantically similar. Actually converted together.

The graph is rebuilt nightly from all conversion data. Atom selection reads it directly.

06Presentation learning

Testing what works, not just what fits

Vector search finds the right atoms. The co-conversion graph finds the right supporting atoms. But which component order converts best? A StatGrid before an AtomCard, or after? Spectare tests this automatically. Set an exploration rate in Settings and a configurable share of visitors see an experimental arrangement. The arrangement is labelled with a strategy tag: data-led, outcome-led, question-led, social-proof-led, or technical-led. Every arrangement is recorded with its impressions and conversions, on every path: client-side, SSR, and script tag, on cache hits as well as fresh assemblies.

Then the loop closes. Once an arrangement clears your signal threshold, Claude is told which arrangements convert best for this visitor’s audience and stage, with the rates that earned them. It prefers a proven arrangement when the atoms support one, and ignores it when they do not: a winning shape built from the wrong content converts worse than an honest one. Exploration runs blind to this, on purpose, so it keeps finding arrangements the data has not seen yet. The atom content never changes. Only the presentation is tested.

There is a discipline to when a winner counts. Ahead is not the same as winning: a 12% rate beating a 10% rate across a hundred visits each sits well inside the noise. So Spectare holds every arrangement’s rate as a confidence interval, not a single number, and only names a winner once that interval clears the runner-up, once its worst case still beats the other’s best case. Until then the honest verdict is that it is still gathering data, and that is exactly what your analytics show, per audience and stage: a statistically real winner, or a clear not-yet, never a coin toss dressed up as a result.

Visitor arrives

intent known from qualify

Exploration check

is this visitor in the configured exploration share?

most visitors · exploit

Proven arrangement

served from Redis cache

exploration share · explore

New arrangement

bypasses cache; strategy tag assigned

Impression recorded

variantId · audience · stage · components

no conversion

Session ends

impression counted, no conversion

conversion

Conversion recorded

linked to this variant, audience, stage

What's working

variants ranked by conversion rate once signal threshold reached

Set exploration rate and signal threshold in Settings. Results appear in Analytics once a variant reaches your chosen impression threshold.

07Live on this page

Everything above just happened for you

This block was assembled by the exact pipeline described above: your signals were classified into an intent, atoms were selected from the library, and the layout was composed and cached, before the page reached you. Here is what it produced for this visit.

Intent detection that actually works

Read visitor intent from referrer, UTM signals, and page context. Assemble personalized experiences in server-rendered HTML before any JavaScript runs.

Silent intent detection plus explicit visitor input

Spectare works out who each visitor is the moment they arrive, without asking anything. It reads the referrer, UTM parameters, the page they landed on, and any earlier pages from the session, then Claude classifies the visitor's likely role, buying stage, and intent type. On Spectare's own server-rendered pages this happens before the page is sent, so the personalised content is inlined into the initial HTML, before any JavaScript runs.

The classification is cached by signal pattern, so a repeat pattern skips the AI call and resolves in milliseconds. Nothing about the visitor is stored: no tracking cookies, no saved profiles. Every classification is fresh, session-only, used immediately, then discarded.

Personalised content arrives in the HTML with no client JavaScript

Adobe Target, Dynamic Yield, and most other personalisation platforms default to the same delivery model: a JavaScript snippet runs after the browser has painted the page, detects the visitor, fetches a variant, and swaps the content in. The result is a flash of the default content followed by a visual shift as the personalised version replaces it. Spectare eliminates that entirely on warm cache hits.

When a cached assembly exists for a visitor's intent signal, Spectare's ServerAssemblyRenderer returns a pure server component. The personalised HTML is embedded directly in the initial server response, and no client JavaScript is required for the personalised section at all. The VariantTracker, a thin client component, handles conversion attribution in the background without blocking render or hydration.

On a cold cache hit, where no prior assembly exists for that intent pattern, the page falls back to the client shimmer while the AI assembles a fresh response. This keeps first-visit latency predictable without compromising personalisation accuracy. Once that assembly is cached, every subsequent warm hit for the same intent pattern is served as pure server-rendered HTML.

This delivery model now covers the homepage, features overview, features sub-pages for AI, analytics, and integration, the compare page, use-cases, and how-it-works. The integration features page, which previously had no personalisation at all, is now fully wired up with the same SSR path as the rest of the site.

08For AI agents

The same content, read by machines

More of your buyers research through AI, and the visitor is often an agent. The same atom library that personalises pages for people is also published as machine-readable data, so an assistant can read what you offer, accurately and current, without scraping a rendered page.

  • Discovery: your site serves an llms.txt describing what you offer and where to find it.
  • Content: every published atom is available as clean JSON at /api/content, with a stable slug per item.
  • Hand-off: an assistant can call the qualify endpoint with what its user wants and get back a link to a page personalised for that person, so the referral lands on a tailored experience, not a generic one.

See it running on a real site

The demo page runs the full qualify and assemble pipeline live. Describe your site and watch intent classification and content assembly happen in real time.