Building a Custom Product Configurator on Shopify

Last updated
Expert reviewed
5 min read
Jacques Blom
Jacques Blom
CTO at Fudge.

Key takeaways

  • A Shopify product configurator lets shoppers build a made-to-order product on the PDP - pick a wood, a size, an engraving - and send those choices to the cart.
  • Variants handle priced, stocked combinations. The limit is now 2,048 variants per product and still 3 options per product. Anything beyond that needs another approach.
  • Line item properties capture free-text and non-priced choices (engraving text, gift notes) and travel with the order. They do not change price or track inventory on their own.
  • Metafields store fixed product data (materials, lead times, option lists). They are merchant-defined, not customer input.
  • The honest split: apps are fast to install but add scripts and monthly fees; native code gives you a lean, theme-owned configurator with no third-party dependency. That native path is what Fudge builds.

A Shopify product configurator is the interface on a product page where a shopper assembles a built-to-order item before adding it to the cart. Think configurable furniture, custom jewellery, build-your-own bundles, or made-to-order kits. The shopper picks options, the price updates, and the selections get attached to the order so your team can fulfil it correctly.

This guide covers the real building blocks: variants, line item properties, product options, metafields, and custom Liquid and JavaScript. It compares the native-code approach against configurator apps without pretending either is free of tradeoffs. Every limit below is checked against Shopify’s own documentation.


Why you can trust us

Jacques has over 15 years of development experience and has worked with hundreds of Shopify stores. We built Fudge - an AI-native Shopify page builder and store editor with a 4.8 rating and a Built for Shopify badge. We write Liquid, JavaScript, and CSS directly into themes every day, so the tradeoffs in this guide come from shipping real configurators, not theory.


What a product configurator needs to do

A configurator has four jobs. Each one maps to a different Shopify primitive, and choosing the wrong primitive is where most builds go wrong.

  1. Present options - swatches, dropdowns, buttons, text inputs, file uploads.
  2. React to selections - show or hide dependent options, update the live price, block invalid combinations.
  3. Price the result - some choices change price (a larger size), some do not (a gift message).
  4. Carry choices to the order - so warehouse and fulfilment see exactly what to make.

The rest of this guide walks each Shopify feature and shows which job it is built for.


Approach 1: variants

Variants are Shopify’s native way to model priced, stocked combinations of a product. A “Size” option and a “Colour” option produce a grid of variants, each with its own price, SKU, and inventory count.

The variant limits you need to know

Shopify raised the variant ceiling in October 2025. The current figures:

That second limit is the one that trips up configurators. More variants does not mean more options. If your build-to-order product needs five or six independent choices, variants alone cannot express it, no matter how high the variant count goes.

On the developer side, a single-product GraphQL query such as product or productByHandle can now return up to 2,000 variants, and the productSet mutation can create or update up to 2,000 variants asynchronously in one call.3

When variants are the right tool

Use variants when every combination has a real price and real stock, and you have three options or fewer. A t-shirt in three sizes and four colours is 12 variants. That belongs in variants.

Variants are also the only mechanism that Shopify prices and tracks inventory for natively. If a choice must reduce stock, it has to be a variant.

Where variants run out

Variants break down for true made-to-order products:

That is where the other primitives come in.


Approach 2: line item properties

Line item properties are name-value pairs attached to a specific item in a specific order. They are the workhorse of configurators. Unlike variants, they do not need to exist ahead of time and do not track inventory.

You capture them with form inputs named properties[...] inside the product form:

<form action="/cart/add" method="post" enctype="multipart/form-data">
    <input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}" />

    <label for="engraving">Engraving text</label>
    <input type="text" id="engraving" name="properties[Engraving]" maxlength="20" />

    <label for="wrap">Gift wrap</label>
    <select id="wrap" name="properties[Gift wrap]">
        <option value="None">None</option>
        <option value="Standard">Standard</option>
    </select>

    <button type="submit">Add to cart</button>
</form>

Whatever the shopper types or selects becomes a property on that line item, visible on the cart, the checkout, the order, and the confirmation email.4

Hidden properties

Prefix a property name with an underscore and Shopify hides it from the customer at checkout while still saving it on the order.5 Use this for internal data your team needs but the shopper should not see:

<input type="hidden" name="properties[_config_id]" value="cfg_8842" />

Most themes also skip underscore-prefixed properties in the cart, though not every theme does, so check your cart template.

Passing selections through the AJAX cart

If your configurator adds to cart without a page reload, use the AJAX Cart API. Send a properties object to /cart/add.js:

fetch('/cart/add.js', {
    method: 'POST',
    headers: {'Content-Type': 'application/json'},
    body: JSON.stringify({
        id: variantId,
        quantity: 1,
        properties: {
            Engraving: 'For Sam',
            'Gift wrap': 'Standard',
            _config_id: 'cfg_8842',
        },
    }),
})

One behaviour to know: a POST that includes properties overwrites the entire properties object for that line item. You cannot patch a single key, and you cannot reset properties to an empty object once set - you have to remove and re-add the line item.6

Want a configurator built into your theme?
Try Fudge for Free

Approach 3: metafields

Metafields are merchant-defined data attached to a product, variant, or other resource. They are set once in the admin, not entered by the shopper.7

In a configurator, metafields hold the fixed reference data your logic reads from:

You read them in Liquid to drive the UI:

{% assign woods = product.metafields.custom.wood_options.value %}
{% for wood in woods %}
  <button data-price-delta="{{ wood.price_delta }}">{{ wood.name }}</button>
{% endfor %}

The rule of thumb: metafields describe the product, line item properties record the shopper’s choice. For a deeper walkthrough, see our guide on adding metafields to Shopify products.


Building the configurator UI

With the data model settled, the front end is Liquid for the initial render and JavaScript for interactivity. See our guides on customizing a Shopify product page and adding custom JavaScript in Shopify for the mechanics.

Option pickers

Render each option as swatches, buttons, dropdowns, or inputs. Priced choices point at variants; non-priced choices feed line item properties. A clean pattern is to carry the price impact on the element itself with a data- attribute so your script can read it without a lookup.

Conditional logic

Made-to-order products have dependencies. A “monogram position” option should only appear once “add monogram” is checked. Handle this by listening for change events and toggling the dependent fields:

document.querySelector('#add-monogram').addEventListener('change', (e) => {
    document.querySelector('#monogram-options').hidden = !e.target.checked
})

Live price updates

Base price plus the sum of selected deltas. Recompute on every change:

function updatePrice() {
    let total = basePrice
    document.querySelectorAll('[data-selected="true"]').forEach((el) => {
        total += Number(el.dataset.priceDelta || 0)
    })
    priceEl.textContent = formatMoney(total)
}

One caution: the displayed price is cosmetic. Shopify charges the price of the variant that is actually added to the cart. If an option genuinely changes what the customer pays, it must be a variant or a priced add-on product, not a line item property. Line item properties do not carry a price.


Validation

A configurator that lets shoppers submit incomplete or invalid builds creates fulfilment problems. Validate before the add-to-cart request fires.

Client-side checks are for user experience only. They can be bypassed. For anything that must not be violated - a maximum quantity, a banned combination, an order-value floor - enforce it with a Shopify Function (cart or checkout validation), which runs server-side on Shopify’s platform and cannot be skipped from the browser.


Performance

Configurators add scripts to your most commercially important page. Watch three things.

A lean configurator protects conversion. For the broader picture, see our guide on the high-converting Shopify product page.


Native code vs configurator apps

Both approaches ship working configurators. The difference is what you own and what you carry.

FactorNative code (Liquid, JS, metafields)Configurator app
Setup speedSlower to build the first timeFast to install and configure
Ongoing costNone beyond build timeRecurring monthly fee
PerformanceLean, PDP-scoped, no extra vendor scriptAdds the app’s bundle to product pages
CustomizationFull control over markup and logicBounded by the app’s settings
Data ownershipLives in your theme and order dataSome logic lives in the app
Dependency riskNone - it is your codeBreaks or changes if the app does
Non-priced optionsLine item properties, unlimitedUsually supported
Priced, stocked optionsNative variantsApp or variants

Apps are the right call when you need something live this week, the configurator is standard, and a monthly fee is acceptable.

Native code wins when performance matters, you want no third-party dependency on a revenue-critical page, or your product needs logic an app’s settings cannot express. The tradeoff has historically been build time and needing a developer.

That is the gap Fudge closes. Fudge is a Shopify-native AI system that writes Liquid, JavaScript, and CSS straight into your theme. You describe the configurator you want, and it produces production-ready, theme-owned code - option pickers, conditional logic, live pricing, line item properties wired to the cart - without pulling in a third-party app. You get the lean native result with far less of the build cost.

Describe your configurator, get theme-native code.
Try Fudge for Free

Putting it together

A typical made-to-order configurator combines all four primitives:

Model the data first, build the UI second, validate before the cart, and keep the page lean. If a choice must change price or reduce inventory, it has to be a variant. If it is information you attach to the order, it is a line item property. For custom option display, our guide on adding custom Liquid logic in Shopify covers the templating patterns.


FAQ

How many variants and options can a Shopify product have?

A product can have up to 2,048 variants, raised from 100 in October 2025. The options-per-product limit did not change: it is still 3 (for example Size, Colour, Material). If your configurator needs more than three independent choices, use line item properties for the extra options rather than trying to add more variants.

What is the difference between variants and line item properties?

Variants are priced, stocked combinations that Shopify manages natively - each has its own price, SKU, and inventory. Line item properties are name-value pairs the shopper enters (like engraving text) that attach to the order but do not change price or track stock. Use variants when a choice affects price or inventory, line item properties for everything else.

Can a line item property change the product price?

No. Line item properties record information on the order but carry no price. If a configurator option genuinely changes what the customer pays, it must be a variant or a separate priced add-on product. Any price you show in JavaScript is cosmetic - Shopify charges the price of the variant that is actually added to the cart.

Do I need an app to build a Shopify product configurator?

No. You can build a full configurator in native theme code using variants, line item properties, metafields, and custom JavaScript. Apps are faster to install but add a recurring fee and load their own scripts on your product pages. Native code is leaner and has no third-party dependency, which is the approach Fudge generates directly in your theme.

How do I pass configurator selections to the cart?

Use inputs named "properties[Name]" inside the product form, or send a properties object to /cart/add.js if you add to cart with AJAX. Note that an AJAX POST including properties overwrites the entire properties object for that line item - you cannot patch a single key or reset it to empty without removing and re-adding the line item.

How do I hide internal configurator data from the customer?

Prefix the property name with an underscore, for example properties[_config_id]. Shopify hides underscore-prefixed properties from the customer at checkout while still saving them on the order, so your fulfilment team can read them. Most themes also skip them in the cart, but verify your cart template since not every theme does.

How do I validate configurator input so orders are always buildable?

Use client-side JavaScript to require mandatory options, cap free-text length, and enforce dependent fields before the add-to-cart request fires. Client checks are for user experience and can be bypassed, so enforce hard rules (max quantity, banned combinations, order minimums) with a Shopify Function that runs server-side and cannot be skipped from the browser.

Jacques's signature
Ship a configurator without the app tax.

Footnotes

  1. Shopify Developer Changelog, “The product variant limit is now 2048 for all merchants” (effective October 15, 2025): https://shopify.dev/changelog/the-product-variant-limit-is-now-2048-for-all-merchants

  2. Shopify Help Center, “Adding variants” (up to 3 options per product): https://help.shopify.com/en/manual/products/variants/add-variants

  3. Shopify Developer Changelog, “Enhanced variant query limits for single product queries” (up to 2000 variants per single-product query, API version 2025-01): https://shopify.dev/changelog/enhanced-variant-query-limits-for-single-product-queries

  4. Shopify Liquid reference, “line_item” object (properties captured via properties[...] inputs): https://shopify.dev/docs/api/liquid/objects/line_item

  5. Shopify Liquid reference, “line_item” object (underscore prefix hides a property from customers at checkout): https://shopify.dev/docs/api/liquid/objects/line_item

  6. Shopify Ajax API, “Cart API reference” (a POST including properties overwrites the entire properties object): https://shopify.dev/docs/api/ajax/reference/cart

  7. Shopify Help Center, “Metafields” (merchant-defined custom data on products and other resources): https://help.shopify.com/en/manual/custom-data/metafields

You might also be interested in

How to Add 360-Degree Product Photography to Shopify
Add Shopify 360 product photography to your PDP. Covers frame capture, native 3D media, spin apps, a custom JS spin viewer, and lazy-loading.