Dawn Theme: Adding Multiple Custom Line Items

Topic summary

Multiple users report that custom line item properties (custom key–value fields attached to a cart item) in the Shopify Dawn theme are not appearing in the cart or checkout.

Original poster shows cart template code that loops through item.options_with_values and item.properties, and also iterates cart.line_items to print properties, excluding blanks and underscores. Despite this, values do not render. Their product-form.js submits via fetch to cart_add_url with a properties payload (e.g., { Color: this.itemProperty.value }) sourced from fieldset#Color-Select, alongside serialized form data.

Another participant asks why adding attributes in Dawn 2.0 “does not take effect,” referencing a screenshot (image appears central but cannot be viewed here). A moderation note warns against hijacking threads. A third participant confirms the same symptom: custom fields added to the product template and output code in the cart exist, but properties still don’t show.

No solution or workaround is provided. The thread remains open with key unanswered questions about capturing and rendering multiple line item properties in Dawn.

Summarized with AI on March 2. AI used: gpt-5.

After following a few tutorials and looking elsewhere on this forum, I am still not able to get my multiple custom line items to show up in the cart. I would also like these to be shown at checkout. I put my line item code in the product form on main-product.liquid. See below.


This Code is in my main-cart-items.liquid

<dl>
                        {%- if item.product.has_only_default_variant == false -%}
                          {%- for option in item.options_with_values -%}
                            

                              <dt>{{ option.name }}: </dt>
                              <dd>{{ option.value }}</dd>
                            

                          {%- endfor -%}
                        {%- endif -%}

                        {%- for property in item.properties -%}
                        {%- assign property_first_char = property.first | slice: 0 -%}
                        {%- if property.last != blank and property_first_char != '_' -%}
                          
                            <dt>{{ property.first }}: </dt>
                            <dd>
                              {%- if property.last contains '/uploads/' -%}
                                
                                  {{ property.last | split: '/' | last }}
                                
                              {%- else -%}
                                {{ property.last }}
                              {%- endif -%}
                            </dd>
                          

                        {%- endif -%}
                      {%- endfor -%}

                      {% for line_item in cart.line_items %}
                        

                        {% unless line_item.properties == empty %}
                          {% for property in line_item.properties %}
                            {{ property.first }}:

                            {% if property.last contains '/uploads/' %}
                              {{ property.last | split: '/' | last }}
                            {% else %}
                              {{ property.last }}
                            {% endif %}
                          {% endfor %}
                        {% endfor %}
                      {% endunless %}
                      
                      </dl>

And here is my product-form.js

class ProductForm extends HTMLElement {
  constructor() {
    super();   

    this.form = this.querySelector('form');
    this.form.addEventListener('submit', this.onSubmitHandler.bind(this));
    this.cartNotification = document.querySelector('cart-notification');
  }

  onSubmitHandler(evt) {
    evt.preventDefault();
    this.itemProperty = document.querySelector('fieldset#Color-Select');
    this.cartNotification.setActiveElement(document.activeElement);
    
    const submitButton = this.querySelector('[type="submit"]');

    submitButton.setAttribute('disabled', true);
    submitButton.classList.add('loading');

    const body = JSON.stringify({
      properties: { Color: this.itemProperty.value },
      ...JSON.parse(serializeForm(this.form)),
      sections: this.cartNotification.getSectionsToRender().map((section) => section.id),
      sections_url: window.location.pathname
    });

    fetch(`${routes.cart_add_url}`, { ...fetchConfig('javascript'), body })
      .then((response) => response.json())
      .then((parsedState) => {
        this.cartNotification.renderContents(parsedState);
      })
      .catch((e) => {
        console.error(e);
      })
      .finally(() => {
        submitButton.classList.remove('loading');
        submitButton.removeAttribute('disabled');
      });
  }
}

customElements.define('product-form', ProductForm);

As you can see above I tried getting atleast one of my line item properties to show and it didn’t work.

What am i missing?

What is the reason why adding attributes to the dawn 2.0 theme in this way does not take effect?

Stop high jacking threads

I’m experiencing the same thing.

I generated my custom product field and added it to my Dawn product template. I see the code to output them on cart template, but it doesn’t seem to be working.