GrowthBook Visual Editor
Overviewโ
GrowthBook's Visual Editor allows non-engineers to create and run experiments by directly manipulating DOM elements on the page. It uses the GrowthBook SDK to apply variation changes at runtime based on a user's sticky bucket assignment.
How It Worksโ
The Visual Editor applies changes by mutating the DOM after the page loads. This works reliably on static or server-rendered elements that are not re-rendered by a client-side framework after hydration.
Important: The GrowthBook dashboard preview runs in an isolated iframe environment that does not replicate client-side hydration. An experiment may appear to work correctly in the dashboard preview but fail in production if the target element is owned by a client-side rendering library like Builder.io.
When to Useโ
Use the Visual Editor only on elements that are:
- Rendered server-side and not re-rendered by a client-side library after hydration
- Outside of any
<BuilderContent />component - Not managed by third-party client-side SDKs (e.g. Yotpo, Builder.io)
Decision Treeโ
When setting up a new experiment, use the following to determine the right approach:
Is the element inside <BuilderContent />?
โโโ Yes, it's a content/copy change โ use Builder.io native A/B testing
โโโ Yes, it's a logic/feature change โ use checkGate in the route loader + feature flag
โโโ No, it's a standard React component โ GrowthBook Visual Editor or feature flag both work
Components the Visual Editor Can Be Used Onโ
- PDP
- PLP (excluding Builder-rendered components such as Rec Tray)
Components the Visual Editor Cannot Be Used Onโ
- Any component inside
<BuilderContent />(Builder.io owns and re-renders these) - Yotpo widgets
- Any component that re-renders client-side after hydration
Why Builder.io Is Incompatibleโ
When a page with a Builder component loads, the following sequence occurs:
- Server renders the page with the GrowthBook evaluated variant
- GrowthBook Visual Editor fires and applies the variation DOM mutation โ
- Builder.io client SDK hydrates and re-renders its content blocks
- Builder overwrites the mutated element with the original control content โ
This causes the variation to flash briefly before snapping back to control. From a data perspective, the user is tracked as having seen the variation when they actually saw the control โ corrupting experiment results.
For experiments targeting Builder content, please see Component Experimentation or Page Model Experimentation.
Sticky Bucketing and the Visual Editorโ
The Visual Editor respects sticky bucketing โ once a user is assigned a variation, they will continue to see that variation on return visits. However, if the DOM mutation is overwritten by client-side re-rendering, the user will see the control despite being correctly bucketed. This creates:
- False exposure tracking โ users recorded as seeing a variation they never actually saw
- Flickering โ brief flash of the variation before snapping back to control
- Corrupted experiment data โ variation and control groups are no longer reliable, leading to potential multiple-exposure warnings.
Troubleshootingโ
The experiment does not appear in the GrowthBook DevTools extension:
- Confirm the experiment is set to Running in the GrowthBook dashboard
- If not production-ready, disable the
productionenvironment but keepstagingandqaactive - Ensure
enableDevMode: trueis set in the GrowthBook SDK initialization (note: this should be gated to non-production environments)
The experiment appears in DevTools but the variation is not applied:
- Check whether the target element is inside a
<BuilderContent />component โ if so, the Visual Editor cannot be used (see above) - Verify the CSS selector in the Visual Editor matches the actual DOM structure in production โ selectors that work in the dashboard preview may not match the production DOM
- Clear the GrowthBook extension cache in DevTools and reload
The correct variation flashes briefly then reverts to control:
- This is the Builder.io re-render issue described above
- The experiment must be migrated to a feature flag or Builder native A/B test
Sticky bucket assignments are not updating after fixing an experiment:
- Sticky bucket cookies persist previous assignments even after republishing changes to the GrowthBook dashboard
- To force re-bucketing for all users, bump the experiment phase via the "Make Changes" flow in GrowthBook โ this invalidates all existing sticky bucket assignments
- For local testing, manually clear the
gbStickyBuckets__cookies in DevTools โ Application โ Cookies