Home 🛠️ Developers & Advanced Customization

🛠️ Developers & Advanced Customization

Technical guides for developers looking to extend the theme functionalities using code.
2 articles

Using Custom Liquid & HTML

The Freedom theme includes comprehensive "Custom Liquid" and "Custom HTML" tools. These allow you (or your developer) to inject custom code, third-party scripts, or advanced formatting directly through the Theme Editor without modifying the theme's source files. Block vs. Section Depending on where you need the code, you can use either the Section or the Block version. 1. Custom Liquid Section Use this when you want to add a standalone element that spans the width of the page or exists independently of other content. - Location: Can be added anywhere on the Homepage, Product Page, or custom Pages via "Add Section". - Settings: Includes options for padding, margins, and full-width toggles. - Use cases: - Embedding a Google Map <iframe>. - Adding a third-party widget (e.g., an Instagram feed or booking calendar) that needs its own row. - Creating a custom banner using your own HTML/CSS. 2. Custom Liquid Block Thanks to the Theme Blocks architecture, you can drop a Custom Liquid block inside other sections (e.g., within the Product Information section or a Multicolumn section). - Location: Can be nested inside supported sections. - Use cases: - Looping through Lists: Standard text blocks cannot display "List" type metafields (e.g., a list of ingredients or features). Custom Liquid allows you to loop through them and render a bulleted list. - Dynamic Calculations: Performing math operations that aren't possible in standard text blocks (e.g., calculating savings percentage or "Buy 2 and save $X"). - Third-Party App Snippets: Injecting code snippets provided by apps that do not yet support App Blocks (e.g., specific review stars or installment widgets). - Advanced Logic: Showing content based on complex conditions (e.g., "Show this banner only if the product has tag 'Final Sale' AND the customer is logged in"). How to use it 1. Add the Custom Liquid section or block. 2. In the settings panel, paste your code into the Liquid code or HTML field. 3. The editor will render valid HTML and Liquid immediately. Examples Example A: Looping through a List Metafield If you have a metafield defined as a "List of single line text" (e.g., custom.ingredients), a standard text block will not display it correctly. Use Liquid to create a list: <p><strong>Ingredients:</strong></p> <ul> {% for item in product.metafields.custom.ingredients.value %} <li>{{ item }}</li> {% endfor %} </ul> Example B: Dynamic Math Calculation Display how much a customer saves compared to the compare-at price: {% if product.compare_at_price > product.price %} <p class="savings-text"> You save {{ product.compare_at_price | minus: product.price | money }}! </p> {% endif %} ⚠️ Important Disclaimer This feature is intended for users with knowledge of Shopify Liquid, HTML, and CSS. - No Validation: The code is rendered exactly as you type it. Errors in your code can break the layout of the page. - Support: Our support team cannot debug, write, or fix code placed within these sections. If your custom code causes issues, please remove the block to restore functionality.

Last updated on Jan 13, 2026

Javascript Events for Developers

The Freedom theme emits JavaScript events analogous to Shopify's Dawn theme for developer convenience. Whenever a major action occurs (like updating the cart or changing a variant), the theme dispatches a standard browser event to the window object. This allows you to hook into these events using standard JavaScript, making it easy to integrate third-party apps or custom analytics without modifying the theme's core code. How to Listen for Events You can use the standard window.addEventListener method. Important: The event data is assigned directly to the event object properties, rather than inside a detail object. window.addEventListener('cart:update', function(event) { // Access data directly from the event object const cart = event.cartData; console.log('New Total Price:', cart.total_price); }); Cart Events cart:update Fires whenever the cart state changes (item added, removed, quantity changed, or discount applied). Event Data: - source (String): The origin of the action (e.g., product-form, cart-discount, cart-drawer). - cartData (Object): The JSON response from Shopify's Cart API containing items, total price, etc. - variantId (Number): The ID of the specific variant that was updated (optional). Example: window.addEventListener("cart:update", (event) => { console.log("Cart updated via:", event.source); console.log("Items count:", event.cartData.item_count); }); cart:error Fires when a cart action fails (e.g., attempting to add more quantity than is in stock). Event Data: - source (String): Origin (e.g., product-form). - errors (String/Object): Description of the error. - message (String): The error message returned by Shopify. Example: window.addEventListener("cart:error", (event) => { alert("Could not add to cart: " + event.message); }); quantity:update Fires immediately when a quantity input is changed in the UI, before the server request completes. This event does not emit any data. window.addEventListener("quantity:update", () => { console.log("Quantity input changed. UI update pending..."); }); Product Events variant:change Fires when a user selects a variant combination that resolves to a valid variant. This is the primary event for updating prices, SKUs, or availability statuses. Event Data: - data.variant (Object): The full JSON object of the selected variant. - data.sectionId (String): The ID of the section where the change occurred. Example: window.addEventListener("variant:change", (event) => { const variant = event.data.variant; if (variant) { console.log("User selected variant ID:", variant.id); console.log("Variant price:", variant.price); } }); option-value-selection:change Fires immediately when a user clicks an option (swatch, pill, or dropdown), even if a valid variant hasn't been fully resolved yet. Event Data: - data.event (Event): The original DOM click/change event. - data.target (Element): The input element triggered. - data.selectedOptionValues (Array): Array of currently selected values. Example window.addEventListener("option-value-selection:change", (event) => { console.log("Option clicked:", event.data.target.value); console.log("Current selection:", event.data.selectedOptionValues); }); Reference: Event Names For convenience, you can refer to this map of event strings. const THEME_EVENTS = { cartUpdate: 'cart:update', quantityUpdate: 'quantity:update', optionValueSelectionChange: 'option-value-selection:change', variantChange: 'variant:change', cartError: 'cart:error', }

Last updated on Jan 14, 2026