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
-
Render a card with:
<span fs-list-field="Room Types" data-split> Beach Villa, Overwater Villa, Suites </span> -
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
-
-
Try filtering by Overwater Villa or Suites.
-
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!