Iterate over a multi-line text metafield and place in <li>

Topic summary

A developer needed to convert a multi-line text metafield into individual <li> elements in Shopify Liquid. Initial attempts using split with \n or \r\n failed, returning all values in a single list item.

Solution Found:
The issue was resolved using Liquid filters to parse newlines:

{% assign text = product.metafields.custom.product_usp_list.value %}
{% assign lines = text | newline_to_br | strip_newlines | split: "<br />" %}

This converts newlines to <br /> tags, strips them, then splits on the tags to create an array.

Alternative Approaches Discussed:

  • Using a “list of single line text” metafield type with metafield_tag filter
  • Capturing newlines directly with {% capture newline %} (recommended as more stable, since Shopify historically changed <br> to <br />)

Outcome:
The developer successfully implemented the <br /> split method. They initially misunderstood the “list of single line text” suggestion but later clarified that this metafield type doesn’t require preset choices—it’s configured by selecting “list of values” when defining a “Single line text” metafield.

Summarized with AI on October 24. AI used: claude-sonnet-4-5-20250929.

Hi,

I’m trying to iterate over a multi-line text metafield and place each value in a

  • element.
    For example this metafield is filled like so:

    Value A
    Value B
    Value C

    Each value is placed on it’s own line.

    What I want as result is

    <ul>
    <li>Value A</li>
    <li>Value B</li>
    <li>Value C</li>
    </ul>
    

    So what I tried is:

    {% for usp in product.metafields.custom.product_usp_list.value %}
      <li class="product-specification-list__item">{{ usp }}</li>   
    {% endfor %}
    
    {% assign raw_usp = product.metafields.custom.product_usp_list.value %}
    {%- assign usp_array = raw_usp | split: "\r\n" -%} // or  | split: "\n" 
    

    The result is always a single

  • item like so:

    <li class="product-specification-list__item">Value A 
    Value B
    Value C</li>
    

    So my question is if this is even possible like this and if so what is the correct way to iterate over such metafields?

    Thanks!

  • You can instead use “list of single line text” type metafield and use metafield_tag or iterate over mf.value

    If you can’t change the format you should try this:

    {% assign text = product.metafields.custom.product_usp_list.value %}
    
    {% # try this %}
      {% capture newline %}
      {% endcapture %}
    
      {% assign lines = text | split: newline %}
    
    {% # or this %}
      {% assign lines = text | newline_to_br | strip_newlines | split: "<br />" %}
    

    @tim_1 Ok awesome, the ‘<br />‘ did the trick!

    {% assign lines = text | newline_to_br | strip_newlines | split: "<br />" %}
    

    Since the values need to be different for each product working with “list.single_line_text” didn’t work since those are set beforehand.

    This works perfectly fine:

        {% assign text = product.metafields.custom.product_usp_list.value %}
        {% assign lines = text | newline_to_br | strip_newlines | split: "<br />" %}
    
        <ul class="list">
            {%- for line in lines -%}
                <li class="list__item">{{ line }}</li>
            {%- endfor -%}
        </ul>
    

    Thanks!

    Good.
    Personally, I prefer the first way – long time ago Shopify used to output <br> and then one day they switched to <br /> :slight_smile:

    Was puzzled why code stopped working…

    @tim_1 Ok just to be sure: With the first way you are referring to a “single_line_text” field and with the option “Limit to preset choices“??
    I could not find the exact `list of single line text` so I thought you were referring to that.

    Is that correct or did I miss something? (I’m new to Shopify :slight_smile:)

    Thx

    No, I was meaning this:

    And, no, “list of single line text” does not have to be limited to predefined choices.
    When you define your metafield you have a choice whether is will be a single value or a list of values.

    So you first define metafield type as a “Single line text” and then select a “list of values”.

    @tim_1 Omg I feel really dumb now :face_with_peeking_eye:

    Thanks I found it!

    1 Like