Frequently Bought Together
Hand-picked product bundles with checkboxes, a running total and one add-all button.
A paid gift wrap add-on with an optional gift message, right above add to cart.
Important: Before making any changes to your theme, duplicate it in Online Store > Themes so you have a backup.
Gift wrap is one of the easiest add-ons to sell: it costs little to fulfil and shoppers already expect to pay for it. This section adds a checkbox to your product page. When it's ticked, a gift wrap product is added to the cart and the gift message is saved on the order.
Preview with the default settings. Colours, text and layout can all be changed in the theme editor.
In Shopify admin go to Online Store > Themes. Next to the theme you want to edit, click the three dots and choose Edit code.
In the Sections folder click Add a new section, name it lt-gift-wrap-checkbox, delete the placeholder code, paste in the code below and click Save.
Click Customize, go to Products > Default product, click Add section and choose Gift wrap checkbox.
Change the settings in the sidebar, drag the section where you want it, and click Save.
{%- comment -%}
Gift wrap / add-on checkbox by LAUNCHTIP
https://launchtip.com/free-shopify-sections-code
{%- endcomment -%}
{%- liquid
assign wrap = section.settings.wrap_product
assign wrap_variant = wrap.selected_or_first_available_variant
assign wrap_price = wrap_variant.price | money
-%}
{%- if wrap != blank and wrap_variant.available -%}
{%- style -%}
#lt-{{ section.id }} { padding: {{ section.settings.padding }}px 0; }
#lt-{{ section.id }} .lt-gw { display: flex; gap: 12px; align-items: flex-start; border: 1px solid {{ section.settings.border_color }}; border-radius: 8px; padding: 14px 16px; cursor: pointer; background: {{ section.settings.background }}; }
#lt-{{ section.id }} .lt-gw input[type="checkbox"] { width: 18px; height: 18px; margin-top: 2px; accent-color: {{ section.settings.accent }}; flex-shrink: 0; }
#lt-{{ section.id }} .lt-gw img { width: 48px; height: 48px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
#lt-{{ section.id }} .lt-gw__title { font-weight: 600; display: block; }
#lt-{{ section.id }} .lt-gw__text { font-size: 0.9em; opacity: 0.8; }
#lt-{{ section.id }} .lt-gw__message { display: none; width: 100%; margin-top: 10px; padding: 10px; border: 1px solid {{ section.settings.border_color }}; border-radius: 6px; font: inherit; resize: vertical; }
#lt-{{ section.id }}.is-checked .lt-gw__message { display: block; }
{%- endstyle -%}
<div
id="lt-{{ section.id }}"
class="page-width"
data-variant-id="{{ wrap_variant.id }}"
data-cart-url="{{ routes.cart_url }}"
data-property="{{ section.settings.property_name | escape }}"
>
<label class="lt-gw">
<input type="checkbox" class="lt-gw__check">
{%- if section.settings.show_image and wrap.featured_image != blank -%}
{{ wrap.featured_image | image_url: width: 120 | image_tag: loading: 'lazy', alt: wrap.title }}
{%- endif -%}
<span>
<span class="lt-gw__title">{{ section.settings.heading | replace: '[price]', wrap_price }}</span>
<span class="lt-gw__text">{{ section.settings.text | replace: '[price]', wrap_price }}</span>
</span>
</label>
{%- if section.settings.show_message -%}
<textarea
class="lt-gw__message"
rows="2"
maxlength="200"
placeholder="{{ section.settings.message_placeholder | escape }}"
aria-label="{{ section.settings.message_placeholder | escape }}"
></textarea>
{%- endif -%}
</div>
<script>
(function () {
var root = document.getElementById('lt-{{ section.id }}');
if (!root || root.dataset.ready) return;
root.dataset.ready = '1';
var checkbox = root.querySelector('.lt-gw__check');
var message = root.querySelector('.lt-gw__message');
var variantId = Number(root.dataset.variantId);
var property = root.dataset.property;
function productForm() {
return document.querySelector('main form[action*="/cart/add"]') ||
document.querySelector('form[action*="/cart/add"]');
}
function setProperty(form, name, value) {
var input = form.querySelector('input[data-lt-gift="' + name + '"]');
if (!value) { if (input) input.remove(); return; }
if (!input) {
input = document.createElement('input');
input.type = 'hidden';
input.name = 'properties[' + name + ']';
input.dataset.ltGift = name;
form.appendChild(input);
}
input.value = value;
}
function sync() {
var form = productForm();
root.classList.toggle('is-checked', checkbox.checked);
if (!form) return;
setProperty(form, property, checkbox.checked ? 'Yes' : '');
setProperty(form, 'Gift message', checkbox.checked && message ? message.value.trim() : '');
}
function addWrapToCart() {
return fetch(root.dataset.cartUrl + '.js', { headers: { Accept: 'application/json' } })
.then(function (r) { return r.json(); })
.then(function (cart) {
var already = cart.items.some(function (item) { return item.variant_id === variantId; });
if (already) return;
return fetch(window.Shopify && Shopify.routes ? Shopify.routes.root + 'cart/add.js' : '/cart/add.js', {
method: 'POST',
keepalive: true,
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({ items: [{ id: variantId, quantity: 1 }] })
});
})
.then(function () {
document.dispatchEvent(new CustomEvent('cart:refresh', { bubbles: true }));
})
.catch(function () {});
}
checkbox.addEventListener('change', sync);
if (message) message.addEventListener('input', sync);
var form = productForm();
if (form) {
form.addEventListener('submit', function () {
sync();
if (checkbox.checked) addWrapToCart();
}, true);
}
})();
</script>
{%- elsif request.design_mode -%}
<div class="page-width" style="padding: 20px 0;">
<p style="padding: 14px; border: 1px dashed #999; border-radius: 8px;">Gift wrap: pick your gift wrap product in the section settings.</p>
</div>
{%- endif -%}
{% schema %}
{
"name": "Gift wrap checkbox",
"tag": "section",
"class": "lt-gift-wrap-section",
"settings": [
{
"type": "product",
"id": "wrap_product",
"label": "Gift wrap product",
"info": "Create a product called Gift wrap with the price you want to charge, then pick it here."
},
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Add gift wrap for [price]",
"info": "[price] is replaced with the gift wrap price."
},
{
"type": "text",
"id": "text",
"label": "Text",
"default": "Wrapped by hand with a handwritten note."
},
{
"type": "checkbox",
"id": "show_image",
"label": "Show gift wrap image",
"default": true
},
{
"type": "checkbox",
"id": "show_message",
"label": "Show gift message box",
"default": true
},
{
"type": "text",
"id": "message_placeholder",
"label": "Gift message placeholder",
"default": "Add a gift message (optional)"
},
{
"type": "text",
"id": "property_name",
"label": "Line item label",
"default": "Gift wrap",
"info": "Shown on the order next to the product being wrapped."
},
{
"type": "color",
"id": "accent",
"label": "Checkbox colour",
"default": "#111111"
},
{
"type": "color",
"id": "border_color",
"label": "Border colour",
"default": "#e5e5e5"
},
{
"type": "color",
"id": "background",
"label": "Background",
"default": "#ffffff"
},
{
"type": "range",
"id": "padding",
"label": "Vertical padding",
"min": 0,
"max": 60,
"step": 4,
"unit": "px",
"default": 12
}
],
"presets": [
{
"name": "Gift wrap checkbox"
}
]
}
{% endschema %}
| Setting | Default |
|---|---|
| Gift wrap product Create a product called Gift wrap with the price you want to charge, then pick it here. | — |
| Heading [price] is replaced with the gift wrap price. | Add gift wrap for [price] |
| Text | Wrapped by hand with a handwritten note. |
| Show gift wrap image | On |
| Show gift message box | On |
| Gift message placeholder | Add a gift message (optional) |
| Line item label Shown on the order next to the product being wrapped. | Gift wrap |
| Checkbox colour | #111111 |
| Border colour | #e5e5e5 |
| Background | #ffffff |
| Vertical padding | 12px |
Further reading: Best product add-ons apps for Shopify
The gift wrap is added in the background when the shopper presses add to cart. Most themes show it the next time the cart opens. If your drawer opens before it's added, refresh the drawer or turn on the cart page in your theme settings.
Yes. Remove the check for an existing gift wrap line in the script and it will add one gift wrap for every add to cart.
Line item properties show on the order page in Shopify admin. Most packing slip templates include them; if yours doesn't, add line_item.properties to the template in Settings > Shipping and delivery > Packing slip template.
SellUp shows checkbox add-ons like gift wrap and warranties on any product, styled to match your theme, and adds them in the same click as the main item. No theme code to test or maintain.
Try SellUpHand-picked product bundles with checkboxes, a running total and one add-all button.
"You're £12 away from free shipping" with a bar that fills as the cart grows.
Buy 2 save 10%, buy 3 save 15%: a tiered pricing table with the price each worked out.
Discover more code snippets to enhance your Shopify store.
View All Sections