Skip to main content
A first-time visitor loads your page, sees the current version for a moment, and then it switches to the variant. Returning visitors don’t see it. That’s expected behaviour, not a bug — and it has three fixes depending on your stack.

Why it happens

getVariant() is synchronous and needs experiment config to answer correctly. Where that config comes from differs by visitor:
  • Returning visitor — config is in local storage from a previous visit, read synchronously before first paint. Correct immediately, no flicker.
  • First-time visitor — no cache. The SDK returns control while the first config fetch is in flight, then re-renders with the real assignment when it lands.
Nothing is hidden and nothing is lost: exposure fires on the variant that actually rendered, so your data stays correct either way. The problem is purely visual. Config is cached for 24 hours, so this affects genuinely new visitors and people who cleared storage — not your regular traffic.

Fix 1 — Resolve on the server (best)

If you’re on Next.js, the server can resolve variants before any HTML is sent, so the first paint is already correct for everyone. Nothing is hidden and there’s no timeout to tune.
Full setup in Next.js. Other server frameworks can do the same via resolveExperiments() from @trevosdk/browser/server.

Fix 2 — Anti-flicker snippet

If you can’t resolve server-side, hide the page until variants are ready. Inline this in <head>, before anything renders:
It sets body { opacity: 0 } and reveals automatically once config arrives — or after a 1 second safety timeout, whichever comes first. That timeout is the important part. If an ad blocker, a CSP rule, or a network failure stops the SDK loading, the page reveals anyway rather than staying blank. Raise it if your users are on slow networks, but understand the trade:
You’re choosing between a brief flash and a brief blank page. Neither is free — the blank page is usually less jarring, but it’s worse if it goes wrong. For full control, initialise with manualReveal: true and call trevo.reveal() yourself once you’ve committed the variant.

Fix 3 — Design around it

Often the cheapest answer. A first-paint swap is only visible if the tested element is visible on first paint.
  • Test things below the fold, or behind an interaction — a modal, a second step, a menu
  • Gate rendering on readiness where the surface can wait:
  • Or await trevo.ready() before rendering the section under test
If your experiment is on a hero CTA for a landing page whose whole audience is first-time visitors, that’s exactly the case for fix 1 or 2.

Which to choose