Single Finsweet filter to feed 2 CMS collection with continuous data?

Hi Finsweet team,

I’m building a blog page using CMS Filter v2 + API, and the filtering logic (TYPE + conditional SUBTYPE) is now working correctly.

Layout

The page has two separate content sections (due to different right-hand rails):

  • Section 1: filter panel + top blog feed + full rail

  • Section 2: lower blog feed + banner-only rail

These sections must remain structurally separate.

Requirement

I need the filtered results to behave as one continuous dataset, but be visually split:

  • Top feed: first 5 filtered results

  • Bottom feed: remaining filtered results

Examples:

  • 2 results → top: 2, bottom: 0

  • 8 results → top: 5, bottom: 3

  • 14 results → top: 5, bottom: 9

Issue

Using two CMS lists with:

  • Show:5 / Skip:0

  • Show:5 / Skip:5

doesn’t work, as the split happens before filtering, not after.

Question

What’s the recommended Finsweet approach for this?

Specifically:

  • treat results as one filtered dataset

  • then render:

    • first 5 items in section 1

    • remainder in section 2

Is this achievable using:

  • shared fs-list-instance

  • CMS Combine / Load

  • or should this be handled via a custom post-filter rendering layer?

Appreciate any guidance before I commit to an architecture.

Thanks!

Hey @dannymartuk!

Great question to ask before committing to architecture — this is exactly the kind of case worth thinking through upfront.

The short answer is: there’s no native Finsweet attribute that splits a single filtered dataset across two structurally separate DOM sections. The Show/Skip approach you tested doesn’t work for the reason you identified — the split happens at the Webflow CMS level, before filtering runs. And using two separate lists with a shared filter won’t give you synchronized “first 5 / remainder” split post-filter either.

The right approach here is the Finsweet API’s renderitems callback — a verified, supported pattern that fires every time filtering produces a new result set. Using it, you can intercept the rendered items array and apply your 5/remainder split logic dynamically after each filter pass.

Here’s the pattern skeleton:

window.FinsweetAttributes = window.FinsweetAttributes || [];
window.FinsweetAttributes.push([
  'list', // Use 'cmsfilter' if you're on v1 (fs-cmsfilter-* attributes)
  (listInstances) => {
    const listInstance = listInstances[0]; // target your specific instance if needed

    const sectionBContainer = document.querySelector('[your-section-b-selector]');
    const SPLIT_AT = 5;

    listInstance.on('renderitems', (renderedItems) => {
      // Clear Section B before each re-render
      sectionBContainer.innerHTML = '';

      renderedItems.forEach((item, index) => {
        if (index < SPLIT_AT) {
          // Section A — make sure it's visible in original list
          item.element.style.display = '';
        } else {
          // Section B — hide in original location, clone into second section
          item.element.style.display = 'none';
          const clone = item.element.cloneNode(true);
          sectionBContainer.appendChild(clone);
        }
      });
    });
  }
]);

A few important notes on this approach:

  • renderedItems gives you the filtered result set in order, after every filter pass — so your 5/remainder split always reflects the currently-filtered dataset, not the raw CMS total.
  • Visibility toggling + cloning is the safer implementation path here. We’re hiding items beyond index 5 in their original location and rendering clones into Section B, rather than moving DOM nodes around (which can affect Finsweet’s internal item tracking).
  • v1 vs v2 key: if you’re using fs-list-* attributes (v2), use ‘list’ as the push key. If you’re still on fs-cmsfilter-* attributes (v1), use ‘cmsfilter’. Your script tag will confirm this.
  • Section B container: you’ll need a dedicated empty div in Section 2 that acts as the overflow items container. Since it’s populated via JS, it doesn’t need to be a Webflow Collection List — a plain Div Block works.

One architectural heads-up: because Section B is populated with clones, any interactions on cloned items (link clicks, hover states, etc.) will work normally. However, if you have Webflow interactions tied to those items, you’ll want to test that clones inherit the needed attributes or replicate the interaction logic.

Could you share your staging URL or a read-only Webflow link? I’d like to see how your sections are structured to give you a more precise implementation — specifically around your list wrapper, the Section 2 container placement, and whether you have fs-list-load in the mix :folded_hands:

Hi Finn,

Thank you for your earlier reply — it was genuinely helpful and much appreciated.

Your guidance around using a single real list, then handling the split via the API/render cycle, helped point us in the right direction. We now have the page structurally working with:

  • one real filtered/paginated list

  • a second lower visual feed populated via cloning/splitting

  • bottom-of-page Previous / Next controls

  • split-feed behaviour functioning as intended

The remaining issue is with sorting.

At the moment, sort is only affecting the currently paginated page slice, rather than the full filtered dataset. So for example, if the overall oldest item sits on page 2, switching to Oldest → Newest won’t pull that item forward globally — it only reorders the items already present on the current page.

What we ultimately need is:

  1. filter the full dataset

  2. sort the full filtered dataset globally

  3. then paginate

  4. then split that paginated result visually across the two feed regions

Would you mind advising on the best Finsweet-compatible approach for that?

Happy to share a staging URL and/or a read-only Webflow link if helpful for reviewing the structure more precisely. I’ll provide that in a private message if that’s possible?

Thanks!

Hi @dannymartuk

Glad you got helped earlier, as for the sorting solution, I would recommend posting this as a new post, that way the whole team gets notified & you get your answer asap

Thanks