How to run custom section experiments
Learn how to run A/B tests and experiments in Framer using Code Overrides and Code Components.
Framer doesn’t include built-in A/B testing for custom sections, but you can integrate third-party analytics or experimentation tools using custom code.
Choosing the right approach
Before you start, decide whether a Code Override or a Code Component is the better fit for your experiment.
Use Code Overrides when:
You’re experimenting on existing layers or Smart Components.
You want to switch between predefined variants without changing layout structure.
The experiment logic should stay lightweight and scoped to a specific layer.
Use Code Components when:
You want a reusable experimentation wrapper across multiple pages or sections.
Editors need to connect variants visually in the canvas.
The experiment logic is complex or shared across multiple components.
If you’re unsure, start with Code Overrides for simple tests and move to Code Components as your experimentation needs grow.
Using Code Overrides with Smart Components
You can use Code Overrides on existing layers or Smart Components to control which variant is shown based on results from a third-party experiment.
On mount, use useEffect to fetch experiment data from your analytics API. Based on the response, return the Smart Component with the appropriate variant set.
For example:
return <Component ref={ref} {...props} variant={selectedVariant} />
This allows you to dynamically switch between Smart Component variants without duplicating layout work.
Passing a dynamic experiment ID
If you’re running multiple experiments across a project, you’ll likely need a dynamic experiment ID.
One approach is to add a Text layer inside the Smart Component and make it visually hidden:
Set width and height to 1px
Set font size to 1px
Position it absolutely in a corner
Disable Pointer Events and User Select
Attach a variable to the Text layer’s content. In your Code Override, you can then read this value from props (for example, props.experimentID) and use it when fetching experiment results.
Creating an experiments Code Component
You can also create a reusable Code Component that handles experiment fetching and variant rendering. This is similar to marketplace integrations like GrowthBook.
Your Code Component can expose the following Property Controls:
Experiment ID using
ControlType.StringControl component using
ControlType.ComponentInstanceVariants using
ControlType.ComponentInstanceinside aControlType.Array
This setup lets editors connect multiple component variants directly in the canvas while keeping experiment logic centralized in code.
Note that this approach works best for components that don’t require full-width (“fill”) responsiveness. This is due to current limitations of ControlType.ComponentInstance. If needed, you can work around this by creating separate instances per breakpoint and toggling visibility for desktop and mobile, similar to components like Ticker or Slideshow.
Adding experiments directly to Code Components
If you’re experimenting on a single Code Component, the most integrated option is to handle variant logic directly inside the component’s code.
On mount, run your experiment check and render the appropriate variant:
const winningVariant = fetch("<https://external-experiment.com>") if (winningVariant === "A") { return <p>A</p> } else { return <p>B</p> }
This keeps styling and logic in one place and avoids external overrides.
Understanding client-side rendering behavior
Framer sites are single-page applications built with React. All third-party experiment logic in code files runs client-side in the browser.
This means fetch requests happen when components mount. For above-the-fold content, this can cause a brief visual flash when variants switch.
To reduce this effect, consider:
Adding appear animations or opacity transitions to mask swaps
Caching experiment results in
localStorageorsessionStorageto persist variants across page navigations
Additional resources
For deeper technical details, refer to the Framer Developer Docs, which cover Code Overrides and Code Components in depth.
Framer doesn’t provide direct support for custom code implementations. If you have general questions about approaches or limitations, you can reach out via our contact page and we’ll help you out.
Framer doesn’t include built-in A/B testing for custom sections, but you can integrate third-party analytics or experimentation tools using custom code.
Choosing the right approach
Before you start, decide whether a Code Override or a Code Component is the better fit for your experiment.
Use Code Overrides when:
You’re experimenting on existing layers or Smart Components.
You want to switch between predefined variants without changing layout structure.
The experiment logic should stay lightweight and scoped to a specific layer.
Use Code Components when:
You want a reusable experimentation wrapper across multiple pages or sections.
Editors need to connect variants visually in the canvas.
The experiment logic is complex or shared across multiple components.
If you’re unsure, start with Code Overrides for simple tests and move to Code Components as your experimentation needs grow.
Using Code Overrides with Smart Components
You can use Code Overrides on existing layers or Smart Components to control which variant is shown based on results from a third-party experiment.
On mount, use useEffect to fetch experiment data from your analytics API. Based on the response, return the Smart Component with the appropriate variant set.
For example:
return <Component ref={ref} {...props} variant={selectedVariant} />
This allows you to dynamically switch between Smart Component variants without duplicating layout work.
Passing a dynamic experiment ID
If you’re running multiple experiments across a project, you’ll likely need a dynamic experiment ID.
One approach is to add a Text layer inside the Smart Component and make it visually hidden:
Set width and height to 1px
Set font size to 1px
Position it absolutely in a corner
Disable Pointer Events and User Select
Attach a variable to the Text layer’s content. In your Code Override, you can then read this value from props (for example, props.experimentID) and use it when fetching experiment results.
Creating an experiments Code Component
You can also create a reusable Code Component that handles experiment fetching and variant rendering. This is similar to marketplace integrations like GrowthBook.
Your Code Component can expose the following Property Controls:
Experiment ID using
ControlType.StringControl component using
ControlType.ComponentInstanceVariants using
ControlType.ComponentInstanceinside aControlType.Array
This setup lets editors connect multiple component variants directly in the canvas while keeping experiment logic centralized in code.
Note that this approach works best for components that don’t require full-width (“fill”) responsiveness. This is due to current limitations of ControlType.ComponentInstance. If needed, you can work around this by creating separate instances per breakpoint and toggling visibility for desktop and mobile, similar to components like Ticker or Slideshow.
Adding experiments directly to Code Components
If you’re experimenting on a single Code Component, the most integrated option is to handle variant logic directly inside the component’s code.
On mount, run your experiment check and render the appropriate variant:
const winningVariant = fetch("<https://external-experiment.com>") if (winningVariant === "A") { return <p>A</p> } else { return <p>B</p> }
This keeps styling and logic in one place and avoids external overrides.
Understanding client-side rendering behavior
Framer sites are single-page applications built with React. All third-party experiment logic in code files runs client-side in the browser.
This means fetch requests happen when components mount. For above-the-fold content, this can cause a brief visual flash when variants switch.
To reduce this effect, consider:
Adding appear animations or opacity transitions to mask swaps
Caching experiment results in
localStorageorsessionStorageto persist variants across page navigations
Additional resources
For deeper technical details, refer to the Framer Developer Docs, which cover Code Overrides and Code Components in depth.
Framer doesn’t provide direct support for custom code implementations. If you have general questions about approaches or limitations, you can reach out via our contact page and we’ll help you out.
Framer doesn’t include built-in A/B testing for custom sections, but you can integrate third-party analytics or experimentation tools using custom code.
Choosing the right approach
Before you start, decide whether a Code Override or a Code Component is the better fit for your experiment.
Use Code Overrides when:
You’re experimenting on existing layers or Smart Components.
You want to switch between predefined variants without changing layout structure.
The experiment logic should stay lightweight and scoped to a specific layer.
Use Code Components when:
You want a reusable experimentation wrapper across multiple pages or sections.
Editors need to connect variants visually in the canvas.
The experiment logic is complex or shared across multiple components.
If you’re unsure, start with Code Overrides for simple tests and move to Code Components as your experimentation needs grow.
Using Code Overrides with Smart Components
You can use Code Overrides on existing layers or Smart Components to control which variant is shown based on results from a third-party experiment.
On mount, use useEffect to fetch experiment data from your analytics API. Based on the response, return the Smart Component with the appropriate variant set.
For example:
return <Component ref={ref} {...props} variant={selectedVariant} />
This allows you to dynamically switch between Smart Component variants without duplicating layout work.
Passing a dynamic experiment ID
If you’re running multiple experiments across a project, you’ll likely need a dynamic experiment ID.
One approach is to add a Text layer inside the Smart Component and make it visually hidden:
Set width and height to 1px
Set font size to 1px
Position it absolutely in a corner
Disable Pointer Events and User Select
Attach a variable to the Text layer’s content. In your Code Override, you can then read this value from props (for example, props.experimentID) and use it when fetching experiment results.
Creating an experiments Code Component
You can also create a reusable Code Component that handles experiment fetching and variant rendering. This is similar to marketplace integrations like GrowthBook.
Your Code Component can expose the following Property Controls:
Experiment ID using
ControlType.StringControl component using
ControlType.ComponentInstanceVariants using
ControlType.ComponentInstanceinside aControlType.Array
This setup lets editors connect multiple component variants directly in the canvas while keeping experiment logic centralized in code.
Note that this approach works best for components that don’t require full-width (“fill”) responsiveness. This is due to current limitations of ControlType.ComponentInstance. If needed, you can work around this by creating separate instances per breakpoint and toggling visibility for desktop and mobile, similar to components like Ticker or Slideshow.
Adding experiments directly to Code Components
If you’re experimenting on a single Code Component, the most integrated option is to handle variant logic directly inside the component’s code.
On mount, run your experiment check and render the appropriate variant:
const winningVariant = fetch("<https://external-experiment.com>") if (winningVariant === "A") { return <p>A</p> } else { return <p>B</p> }
This keeps styling and logic in one place and avoids external overrides.
Understanding client-side rendering behavior
Framer sites are single-page applications built with React. All third-party experiment logic in code files runs client-side in the browser.
This means fetch requests happen when components mount. For above-the-fold content, this can cause a brief visual flash when variants switch.
To reduce this effect, consider:
Adding appear animations or opacity transitions to mask swaps
Caching experiment results in
localStorageorsessionStorageto persist variants across page navigations
Additional resources
For deeper technical details, refer to the Framer Developer Docs, which cover Code Overrides and Code Components in depth.
Framer doesn’t provide direct support for custom code implementations. If you have general questions about approaches or limitations, you can reach out via our contact page and we’ll help you out.
Updated