Testing & Personalizing Native Code Changes
Use Visually to test and personalize changes made directly in your Shopify theme code, no visual editor required.
If you want to make native theme changes without relying on injected code that lives outside your codebase, Visually can still run experiments directly on those changes. This lets your team keep its existing engineering workflow intact, including version control, CI/CD, code reviews, and automated testing.
There are three methods depending on the complexity of your change:
Method 1: CSS Toggling: Switch Between Pre-Rendered Variations
This is best for structural changes where speed matters. Both the control and variant are pre-rendered in the DOM; Visually simply toggles visibility using CSS, which is near-instant and requires no JavaScript execution.
In your native theme code, add both versions and hide the variant by default:
<section data-buy-box="control">
<!-- existing buy box -->
</section>
<section data-buy-box="variant-sticky-cta">
<!-- new buy box variation -->
<div class="buy-box-new">
<h3>Bundle & save 15%</h3>
<button>Add bundle to cart</button>
</div>
</section>
<style>
/* variant hidden by default */
[data-buy-box="variant-sticky-cta"] {
display: none;
}
</style>
In Visually, create a new experience and add a Global CSS snippet to show the variant and hide the control:
[data-buy-box="variant-sticky-cta"] {
display: block;
}
[data-buy-box="control"] {
display: none;
}
Method 2: JS Toggling — Call a Native Function from Visually
Best when your variation requires JavaScript logic to apply. Expose the variant logic as a function on the window object in your native code, then call it from Visually. This keeps the logic inside your codebase and minimises the amount of code that lives inside Visually's editor.
In your native theme code, expose the function:
window.showNewBuyBox = () => {
// logic to show the new buy box
}
In Visually, create a new experience and add a Global Javascript snippet that calls it:
window.showNewBuyBox();
Method 3: Lazy Loaded Module For Larger Code Changes
Best when your variant contains a significant amount of code that you don't want to load for all users. Package the variation as a separate module and import it dynamically via Visually only for the variant group. This approach means your code stays fully in your codebase and Visually simply imports and initialises it.
In your native code, create a new module:
// new-v2-buybox.js
export default renderBuyBox(container, props) {
// logic to be applied
}
In Visually, create a new experience and add a Global Javascript snippet that lazy loads and initialises it:
const module = await import("/assets/buy-box-experiment.js");
const container = document.querySelector("[data-buy-box='control']");
if (!container) return;
module.renderBuyBox(container, {
layout: "subscription-first",
showBundleOffer: true,
showTrustBadges: true
});
Working with Git & Version Control
Visually is designed to complement your existing Git workflow, not replace it. The recommended approach is:
- Build and test your variant in Visually using custom code (Methods 1, 2, or 3 above)
- Run the experiment and identify the winning variant
- Implement only the winning code changes back into Git as a permanent change
- Archive or pause the Visually experience once the winning code is live in your theme
This keeps your Git history clean and only proven, winning changes get committed while Visually handles all the experimentation overhead.
For Methods 2 and 3 in particular, the logic stays entirely in your codebase and Visually simply calls or imports it. This means you can write and manage your experimental code in your own IDE with your full toolchain (AI assistants, linters, automated tests) and only a minimal snippet lives inside Visually's editor.