npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rethink-js/rt-cms-nest

v1.0.0

Published

Attribute-driven CMS content nesting and partial page importing for Webflow and modern websites.

Downloads

16

Readme

rt-cms-nest

rt-cms-nest is a high-performance, enterprise-grade micro-frontend injector that dynamically fetches and nests CMS content seamlessly. It bypasses native Webflow CMS nesting limitations by scraping and injecting target DOM elements asynchronously.

It achieves this without compromising page performance, utilizing an internal architecture featuring:

  • Automatic concurrency management (prevents network throttling and browser UI lockups)
  • Multi-tier caching (Memory and SessionStorage) to instantly serve duplicate requests
  • Attribute-driven configuration requiring zero custom JavaScript
  • Support for multiple independent instances and deep nested hierarchies
  • A clean, predictive global API under window.rtCmsNest
  • Defensive fallbacks, visual skeleton loaders, and robust error handling
  • Built-in Webflow IX2 (Interactions 2.0) re-initialization

Table of Contents


1. Installation

1.1 CDN (jsDelivr)

For traditional HTML/Webflow projects, include the script directly before the closing </body> tag.

<script src="https://cdn.jsdelivr.net/npm/@rethink-js/rt-cms-nest@latest/dist/index.min.js"></script>

1.2 npm & Module Bundlers

For modern build environments (Webpack, Vite, Rollup):

npm install @rethink-js/rt-cms-nest
import "@rethink-js/rt-cms-nest";

// The library automatically initializes upon DOMContentLoaded.
// The API is immediately accessible via window.rtCmsNest

2. Quick Start

To use rt-cms-nest, you establish a relationship between a Destination Page (where content will be injected) and a Source Page (where the content currently lives).

<div data-rt-cms-nest>
  <div data-rt-cms-nest-item>
    <a href="/author/jane-doe" data-rt-cms-nest-link style="display: none;"></a>

    <div data-rt-cms-nest-slot="bio">
      <span class="skeleton-loader">Loading bio...</span>
    </div>
  </div>
</div>
<div data-rt-cms-nest-target="bio">
  <p>Jane Doe is an amazing author with 10 years of experience.</p>
</div>

3. Activation Rules

The package utilizes a zero-config instantiation model. It activates when any element with the data-rt-cms-nest attribute is found on the page.

If no root attributes are found, the script safely remains idle with zero performance footprint. It runs a single highly-optimized query on DOMContentLoaded to build its internal registry.


4. Configuration (HTML Attributes)

All configuration is handled declaratively via data-rt-cms-nest-* attributes. The inheritance flows from Root -> Item -> Slot, allowing granular overrides at every level.

4.1 Root / Wrapper Attributes

Apply these to the primary container wrapping your list of items.

| Attribute | Default | Description | | --------------------------------- | --------------- | --------------------------------------------------------------------- | | data-rt-cms-nest | true | Initializes the instance on this element. | | data-rt-cms-nest-id | Auto-generated | Unique identifier for the instance. Useful for targeted API calls. | | data-rt-cms-nest-concurrency | 6 | Maximum number of simultaneous fetch requests. Prevents 429 errors. | | data-rt-cms-nest-lazy | true | Enables IntersectionObserver to fetch items only near viewport. | | data-rt-cms-nest-root-margin | 600px | Intersection Observer root margin. Determines how early to fetch. | | data-rt-cms-nest-prefetch | none | Options: none, all, viewport, top:N. Preloads requests early. | | data-rt-cms-nest-cache | memory | Options: memory, session, none. Caches HTML string responses. | | data-rt-cms-nest-cache-ttl | 300 | Time to live for cache in seconds. | | data-rt-cms-nest-timeout | 5000 | Fetch request AbortController timeout in milliseconds. | | data-rt-cms-nest-rewrite-links | none | Options: none, absolute, relative. Fixes broken relative links. | | data-rt-cms-nest-sanitize | strip-scripts | Strips <script> and <style> from fetched HTML to prevent XSS. | | data-rt-cms-nest-webflow-reinit | false | Set to true to restart Webflow IX2 engine after DOM injection. | | data-rt-cms-nest-loading-class | none | CSS class applied to the slot while fetching is in progress. | | data-rt-cms-nest-loaded-class | none | CSS class applied to the slot upon successful injection. | | data-rt-cms-nest-error-class | none | CSS class applied to the slot if fetch fails or target is missing. |

4.2 Item Attributes

Add these to the individual cards or rows containing the slots.

| Attribute | Default | Description | | --------------------------- | -------- | --------------------------------------------------------------------- | | data-rt-cms-nest-item | required | Designates the boundaries of a single item context. | | data-rt-cms-nest-link | required | Must be placed on the <a> tag containing the source URL. | | data-rt-cms-nest-on-error | keep | Options: keep, clear, hide, fallback. dictates failure state. | | data-rt-cms-nest-fallback | none | CSS selector of a <template> element to clone if the fetch fails. |

4.3 Slot (Dropzone) Attributes

Add these to the precise DOM nodes where you want content injected.

| Attribute | Default | Description | | ------------------------------ | --------- | ------------------------------------------------------------------------------- | | data-rt-cms-nest-slot | required | The exact string matching the target element on the source page. | | data-rt-cms-nest-mode | replace | Options: replace, append, prepend, before, after. | | data-rt-cms-nest-extract | node | Options: node, text, html, outerhtml, attr:NAME, prop:NAME. | | data-rt-cms-nest-skeleton | none | CSS selector of a <template> to inject as a temporary visual placeholder. | | data-rt-cms-nest-placeholder | keep | Options: keep, clear, hide. How to treat existing inner content initially | | data-rt-cms-nest-wrap | none | Emmet-style string (e.g., div#id.class1) to wrap the incoming node. | | data-rt-cms-nest-add-class | none | Comma-separated list of classes to append to the slot post-injection. |

4.4 Target Page Attributes

These define the specific DOM nodes on the source page that will be isolated and extracted.

| Attribute | Description | | -------------------------------- | ------------------------------------------------------------------------------- | | data-rt-cms-nest-target="name" | Matches the slot name. You can have multiple distinct targets on a single page. |


5. Advanced Extraction & Injection

rt-cms-nest is not limited to simply moving HTML blocks. You can extract specific attributes or properties, enabling sophisticated data mapping.

Extracting an Image Source: If you want to pull an image's URL from a detail page and apply it directly to an <img> tag in your list, use attr:src:

<img
  data-rt-cms-nest-slot="author-avatar"
  data-rt-cms-nest-extract="attr:src"
  src="placeholder-avatar.webp"
/>

<img
  data-rt-cms-nest-target="author-avatar"
  src="https://cdn.example.com/jane-doe.jpg"
/>

Using mode="after" for Layout Preservation: To inject content as a direct sibling of an existing element without creating redundant wrapper <div>s:

<div
  class="existing-header"
  data-rt-cms-nest-slot="extra-details"
  data-rt-cms-nest-mode="after"
>
  <h3>Post Details</h3>
</div>

6. Multiple Instances & State Management

rt-cms-nest handles complex pages effortlessly. You can have multiple CMS lists on the same page, each managed by its own isolated queue, memory cache, and intersection observer.

To create custom loading states, utilize the state classes:

/* Custom CSS applied while the request is in flight */
.is-loading-nest {
  opacity: 0.5;
  pointer-events: none;
  filter: blur(2px);
  transition: all 0.3s ease;
}

/* Custom CSS applied when content fails to load */
.has-nest-error {
  display: none !important;
}

Apply these via your wrapper configuration:

<div
  data-rt-cms-nest="true"
  data-rt-cms-nest-loading-class="is-loading-nest"
  data-rt-cms-nest-error-class="has-nest-error"
></div>

7. Global API

Once initialized, the package exposes a global interface allowing programmatic control, which is essential for Single Page Applications (SPAs) or integrations with third-party filtering libraries.

window.rtCmsNest;

| Method | Description | | -------------- | -------------------------------------------------------------------------------------- | | ids() | Returns an array of active instance IDs on the page. | | get(id) | Returns the specific instance object, exposing its internal queue and item states. | | refresh(id?) | Destroys and re-initializes an instance. Provide an ID, or leave blank to refresh all. | | clearCache() | Purges the internal Map memory and sessionStorage cache. | | destroy(id?) | Safely aborts active fetch requests and disconnects IntersectionObserver instances. |

Integration Example: Finsweet CMS Filter When a user filters a list, the DOM updates dynamically. You must tell rt-cms-nest to rescan the DOM and fetch content for the newly rendered items.

window.fsAttributes = window.fsAttributes || [];
window.fsAttributes.push([
  "cmsfilter",
  (filterInstances) => {
    // Listen for Finsweet's render event
    filterInstances[0].listInstance.on("renderitems", () => {
      if (window.rtCmsNest) {
        // Rescan the DOM and process new items
        window.rtCmsNest.refresh();
      }
    });
  },
]);

8. Lifecycle Events

The script dispatches high-fidelity CustomEvents to the window object. The event.detail payload contains deep context about the operation, allowing you to trigger custom animations or analytics events.

  • rtCmsNest:start (Fired on initialization. Contains instance ID & root element)
  • rtCmsNest:itemStart (Fired when an item enters the viewport and begins fetching)
  • rtCmsNest:itemSuccess (Fired when a slot is successfully populated)
  • rtCmsNest:itemError (Fired on HTTP failure, abort, or missing target)
  • rtCmsNest:complete (Fired when all items within an instance have successfully resolved)

Listening to Events:

window.addEventListener("rtCmsNest:itemSuccess", (event) => {
  const { url, drop, slot, durationMs, fromCache } = event.detail;

  console.log(`Successfully nested ${slot} from ${url} in ${durationMs}ms`);

  // Example: Triggering a GSAP animation on the newly injected node
  gsap.fromTo(drop, { opacity: 0, y: 10 }, { opacity: 1, y: 0, duration: 0.4 });
});

9. Troubleshooting

Content isn't loading

  • Check the console for errors. data-rt-cms-nest-debug="true" will output verbose logs.
  • Ensure data-rt-cms-nest-link is present on a valid <a> tag inside the item boundary.
  • Verify data-rt-cms-nest-target matches the exact string in data-rt-cms-nest-slot. Case sensitivity matters.

Items aren't loading until scrolled

  • This is the intended behavior of the IntersectionObserver to preserve user bandwidth and API limits. Add data-rt-cms-nest-lazy="false" to your wrapper to force immediate fetching on page load.

Target content loses its styles

  • CSS is class-based. Ensure the CSS classes utilized in the target page actually exist in the stylesheet of the destination page. Webflow automatically removes "unused" CSS classes during publishing. Fix: Create a hidden style-guide div on the destination page containing the necessary classes.

Links break when fetched

  • Relative links (<a href="#about-us"> or <a href="/pricing">) lose their context when injected into a new page path. Add data-rt-cms-nest-rewrite-links="absolute" to automatically convert them to fully qualified absolute URLs during injection.

Webflow interactions (IX2) are broken on injected items

  • The Webflow IX2 engine only scans the DOM once on page load. When you inject new HTML, it doesn't know it exists. Add data-rt-cms-nest-webflow-reinit="true" to your wrapper. The library will automatically trigger Webflow.require('ix2').init() after injection is complete.

10. License

MIT License

Package: @rethink-js/rt-cms-nest GitHub: https://github.com/Rethink-JS/rt-cms-nest


by Rethink JS https://github.com/Rethink-JS