Filters only recognize the first tag when splitting a comma-separated field into multiple fs-list-field tags

Hi all,

I store multi-values in one CMS Text field (e.g., Room Types) as a comma-separated string, then split it into individual tags so Finsweet Filters can match each value.

What the CMS outputs (before split)

<!-- Inside each card -->
<span fs-list-field="Room Types" data-split>
  Beach Villa, Overwater Villa, Suites
</span>

What I programmatically convert it into (after split)

<!-- The original combined span is removed -->
<span fs-list-field="Room Types">Beach Villa</span>
<span fs-list-field="Room Types">Overwater Villa</span>
<span fs-list-field="Room Types">Suites</span>

Visual: DOM before vs after

BEFORE
[span fs-list-field="Room Types"] 
  "Beach Villa, Overwater Villa, Suites"

AFTER
[span fs-list-field="Room Types"] "Beach Villa"
[span fs-list-field="Room Types"] "Overwater Villa"
[span fs-list-field="Room Types"] "Suites"

The Problem

When I select a Room Types filter (e.g., Suites), the card is only returned if that value happened to be first in the original comma list.
If Suites was second or third, the card doesn’t show—despite the DOM now having one tag per value (see “AFTER” above).

So, Filters appear to index only the first matching tag that originated from the combined string, even after I’ve split it into separate sibling tags.

Repro Steps

  1. Render a card with:

    <span fs-list-field="Room Types" data-split>
      Beach Villa, Overwater Villa, Suites
    </span>
    
    
  2. Run a splitter (below) that:

    • Splits by comma

    • Creates one sibling <span fs-list-field="Room Types">X</span> per value

    • Removes the original combined span

  3. Try filtering by Overwater Villa or Suites.

  4. Result: the card is shown only if that value was first in the original string.

Expected vs Actual

  • Expected: Any value present as its own fs-list-field="Room Types" tag should make the card match, regardless of original order.

  • Actual: Only the value that was first in the original comma string works reliably.

Minimal splitter I’m using (runs before Finsweet)

<script>
(function () {
  // Run ASAP (inline, before Finsweet script tag)
  function norm(s){ return s.replace(/\u00A0/g,' ').replace(/\s+/g,' ').trim(); }

  function splitAll(root=document){
    const nodes = root.querySelectorAll('[fs-list-field][data-split]');
    nodes.forEach(node => {
      const field = node.getAttribute('fs-list-field');
      const delim = node.getAttribute('data-delim') || ',';
      const parts = (node.textContent || '')
        .split(delim)
        .map(norm)
        .filter(Boolean);

      if (parts.length <= 1) {
        node.textContent = parts[0] || '';
        node.removeAttribute('data-split');
        return;
      }

      // Insert one sibling per value
      const tagName = node.tagName.toLowerCase();
      parts.forEach(val => {
        const el = document.createElement(tagName);
        el.setAttribute('fs-list-field', field);
        el.textContent = val;
        node.parentNode.insertBefore(el, node);
      });

      // Remove the original combined node so Filters never see it
      node.remove();
    });
  }

  if (document.readyState === 'loading') {
    // Do it as early as possible, before Finsweet runs
    document.addEventListener('DOMContentLoaded', splitAll, { once: true });
  } else {
    splitAll();
  }
})();
</script>

Things I’ve Tried

  • Ensuring this splitter runs inline before the Finsweet script tag (so Finsweet only sees the split tags).

  • Removing the original combined node (so there’s no conflicting first-value).

  • MutationObserver for load-more/pagination (same behavior).

Ask

  • Is there an internal indexing/scan timing that still binds the field to the first value it initially sees?

  • Is there an official way to tell Filters to re-scan the final DOM (after my split) and honor all sibling tags under the same fs-list-field?

  • Any recommended pattern for comma-to-multi-tag that Filters fully supports (without CMS multi-ref)?

Thanks!

SOLVED: Shoutout to @Support-Luis for helping me solve this.

The solution was to wrap the split attributes in a fs-list-element=”list” attribute.

Works beautifully since!

2 Likes

I just spent my whole day trying to figure this out. Thanks for posting the answer Conner! Is this referenced in the documentation at all? I’m pretty sure I read everything. I didn’t know I could use fs-list-element=”list” within fs-list-element=”item”.

I think technically it is listed under CMS Nest, which implies you are using a CMS Collection which I am not. So, yes it is documented, just not for this specific use case.

Finsweet doesn’t access the CMS though, so you can really just reengineer how it would read the content on the site, which is what I did to solve this.

@connor when you say:

Do you mean the html should render like this:

<div fs-list-element="list">
   <div fs-list-field="Room Types">Beach Villa</div>
   <div fs-list-field="Room Types">Overwater Villa</div>
</div>

I tried that and it didn’t work.

Also, any chance you could share the live link to your implementation, that would help a ton in reverse engineering it.

cc @Support-Pedro @Support-Luis