Complete the Look

A lifestyle photo next to the products in it, each with its own add to cart button.

One section file Product page, homepage or collection page Edit in the theme editor

Important: Before making any changes to your theme, duplicate it in Online Store > Themes so you have a backup.

Shoppers buy outfits, rooms and setups, not single products. Complete the look pairs a lifestyle photo with the products in it so shoppers can add the rest of the look in a tap. Products with options link to their own page so the shopper can pick a size or colour.

Preview

What you'll build

Look photo

Complete the look

Everything in this photo, ready to add in one tap.

Linen Overshirt £65.00 Add
Relaxed Chinos £55.00 Choose options
Canvas Tote £24.00 Add

Preview with the default settings. Colours, text and layout can all be changed in the theme editor.

Install

Add it to your store in 4 steps

  1. 1

    Open your theme code

    In Shopify admin go to Online Store > Themes. Next to the theme you want to edit, click the three dots and choose Edit code.

  2. 2

    Create the section

    In the Sections folder click Add a new section, name it lt-complete-the-look, delete the placeholder code, paste in the code below and click Save.

  3. 3

    Add it in the theme editor

    Click Customize, go to Products > Default product (or the Home page), click Add section and choose Complete the look.

  4. 4

    Make it yours

    Change the settings in the sidebar, drag the section where you want it, and click Save.

sections/lt-complete-the-look.liquid · 197 lines
{%- comment -%}
  Complete the look by LAUNCHTIP
  https://launchtip.com/free-shopify-sections-code
{%- endcomment -%}
{%- style -%}
  #lt-{{ section.id }} { padding: {{ section.settings.padding }}px 0; }
  #lt-{{ section.id }} .lt-ctl { display: grid; gap: 32px; align-items: center; }
  @media (min-width: 750px) {
    #lt-{{ section.id }} .lt-ctl { grid-template-columns: 1fr 1fr; }
    #lt-{{ section.id }} .lt-ctl--image-right .lt-ctl__image { order: 2; }
  }
  #lt-{{ section.id }} .lt-ctl__image img { width: 100%; height: auto; border-radius: 10px; display: block; }
  #lt-{{ section.id }} .lt-ctl__heading { margin: 0 0 6px; }
  #lt-{{ section.id }} .lt-ctl__text { margin: 0 0 18px; opacity: 0.8; }
  #lt-{{ section.id }} .lt-ctl__item { display: flex; align-items: center; gap: 14px; padding: 12px 0; border-top: 1px solid {{ section.settings.border_color }}; }
  #lt-{{ section.id }} .lt-ctl__item img { width: 64px; height: 64px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
  #lt-{{ section.id }} .lt-ctl__name { flex: 1; min-width: 0; }
  #lt-{{ section.id }} .lt-ctl__name a { color: inherit; text-decoration: none; display: block; }
  #lt-{{ section.id }} .lt-ctl__price { font-size: 0.9em; opacity: 0.75; }
  #lt-{{ section.id }} .lt-ctl__add { background: {{ section.settings.button_color }}; color: {{ section.settings.button_text }}; border: 0; border-radius: 6px; padding: 10px 16px; font: inherit; font-size: 0.9em; font-weight: 600; cursor: pointer; text-decoration: none; white-space: nowrap; }
  #lt-{{ section.id }} .lt-ctl__add[disabled] { opacity: 0.6; cursor: default; }
{%- endstyle -%}

<div
  id="lt-{{ section.id }}"
  class="page-width"
  data-add-url="{{ routes.cart_add_url }}.js"
  data-added="{{ section.settings.added_label | escape }}"
>
  <div class="lt-ctl{% if section.settings.image_position == 'right' %} lt-ctl--image-right{% endif %}">
    <div class="lt-ctl__image">
      {%- if section.settings.image != blank -%}
        {{ section.settings.image | image_url: width: 1200 | image_tag: loading: 'lazy', sizes: '(min-width: 750px) 50vw, 100vw', widths: '400, 600, 800, 1200' }}
      {%- else -%}
        {{ 'lifestyle-1' | placeholder_svg_tag }}
      {%- endif -%}
    </div>

    <div>
      {%- if section.settings.heading != blank -%}
        <h2 class="lt-ctl__heading h2">{{ section.settings.heading }}</h2>
      {%- endif -%}
      {%- if section.settings.text != blank -%}
        <p class="lt-ctl__text">{{ section.settings.text }}</p>
      {%- endif -%}

      {%- for p in section.settings.products -%}
        {%- assign v = p.selected_or_first_available_variant -%}
        <div class="lt-ctl__item">
          {%- if p.featured_image != blank -%}
            {{ p.featured_image | image_url: width: 160 | image_tag: loading: 'lazy', alt: p.title }}
          {%- endif -%}
          <div class="lt-ctl__name">
            <a href="{{ p.url }}">{{ p.title }}</a>
            <span class="lt-ctl__price">{{ v.price | money }}</span>
          </div>
          {%- if p.has_only_default_variant and v.available -%}
            <button type="button" class="lt-ctl__add" data-id="{{ v.id }}">{{ section.settings.button_label }}</button>
          {%- elsif v.available -%}
            <a class="lt-ctl__add" href="{{ p.url }}">{{ section.settings.options_label }}</a>
          {%- else -%}
            <button type="button" class="lt-ctl__add" disabled>{{ section.settings.sold_out_label }}</button>
          {%- endif -%}
        </div>
      {%- else -%}
        {%- if request.design_mode -%}<p>Pick the products in this look in the section settings.</p>{%- endif -%}
      {%- endfor -%}
    </div>
  </div>
</div>

<script>
  (function () {
    var root = document.getElementById('lt-{{ section.id }}');
    if (!root || root.dataset.ready) return;
    root.dataset.ready = '1';

    root.addEventListener('click', function (event) {
      var button = event.target.closest('button[data-id]');
      if (!button || button.disabled) return;
      var label = button.textContent;
      button.disabled = true;
      fetch(root.dataset.addUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
        body: JSON.stringify({ items: [{ id: Number(button.dataset.id), quantity: 1 }] })
      })
        .then(function (response) {
          if (!response.ok) throw new Error('add failed');
          button.textContent = root.dataset.added;
          document.dispatchEvent(new CustomEvent('cart:refresh', { bubbles: true }));
          setTimeout(function () { button.textContent = label; button.disabled = false; }, 2500);
        })
        .catch(function () { button.textContent = label; button.disabled = false; });
    });
  })();
</script>

{% schema %}
{
  "name": "Complete the look",
  "tag": "section",
  "class": "lt-ctl-section",
  "settings": [
    {
      "type": "image_picker",
      "id": "image",
      "label": "Look image"
    },
    {
      "type": "select",
      "id": "image_position",
      "label": "Image position",
      "options": [
        { "value": "left", "label": "Left" },
        { "value": "right", "label": "Right" }
      ],
      "default": "left"
    },
    {
      "type": "text",
      "id": "heading",
      "label": "Heading",
      "default": "Complete the look"
    },
    {
      "type": "textarea",
      "id": "text",
      "label": "Text",
      "default": "Everything in this photo, ready to add in one tap."
    },
    {
      "type": "product_list",
      "id": "products",
      "label": "Products in the look",
      "limit": 6
    },
    {
      "type": "text",
      "id": "button_label",
      "label": "Add button label",
      "default": "Add"
    },
    {
      "type": "text",
      "id": "added_label",
      "label": "Added label",
      "default": "Added"
    },
    {
      "type": "text",
      "id": "options_label",
      "label": "Label for products with options",
      "default": "Choose options"
    },
    {
      "type": "text",
      "id": "sold_out_label",
      "label": "Sold out label",
      "default": "Sold out"
    },
    {
      "type": "color",
      "id": "button_color",
      "label": "Button colour",
      "default": "#111111"
    },
    {
      "type": "color",
      "id": "button_text",
      "label": "Button text colour",
      "default": "#ffffff"
    },
    {
      "type": "color",
      "id": "border_color",
      "label": "Divider colour",
      "default": "#e5e5e5"
    },
    {
      "type": "range",
      "id": "padding",
      "label": "Vertical padding",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "default": 40
    }
  ],
  "presets": [
    {
      "name": "Complete the look"
    }
  ]
}
{% endschema %}
Customization

What you can change in the theme editor

Setting Default
Look image —
Image position Left
Heading Complete the look
Text Everything in this photo, ready to add in one tap.
Products in the look —
Add button label Add
Added label Added
Label for products with options Choose options
Sold out label Sold out
Button colour #111111
Button text colour #ffffff
Divider colour #e5e5e5
Vertical padding 40px
Good to know

Tips for setting it up

  • Use a photo where every product in the list is clearly visible.
  • Single-variant products get an instant Add button. Products with options get a Choose options link instead, so shoppers never get the wrong size.
  • Add the section to the homepage with your best-selling look to give new visitors an easy first basket.

Further reading: Best upsell apps for Shopify

FAQ

Frequently asked questions

How many products can I add?

Up to six per section. Add the section twice for a second look.

Does adding a product open the cart drawer?

The button confirms with Added and asks your theme to refresh the cart. Themes that listen for that event update the cart count straight away.

Can I use a video instead of a photo?

The section uses an image picker. Swap it for a video setting if you want motion, but keep the products visible in the first frame.

SellUp

Want this without the code?

SellUp recommends the next item on every product page and in the cart, matched to your theme, without you hand-picking each look.

Try SellUp

More free sections

New

Gift Wrap Checkbox

A paid gift wrap add-on with an optional gift message, right above add to cart.

New

Frequently Bought Together

Hand-picked product bundles with checkboxes, a running total and one add-all button.

New

Free Shipping Progress Bar

"You're £12 away from free shipping" with a bar that fills as the cart grows.

Explore More Free Sections

Discover more code snippets to enhance your Shopify store.

View All Sections
SellUp Increase AOV with Upsells