Finsweet-table-of-contents

Connect Finsweet Table of Contents with Webflow to generate anchor link navigation automatically from the headings in your content.

Install app
View website
View lesson
A record settings
CNAME record settings
Finsweet-table-of-contents

Webflow renders headings inside Rich Text content but does not build a table of contents from them. You have to create anchor links for long articles by hand, assign an ID to each heading, and keep a sidebar link list in sync. When editors update a post in the Webflow CMS, someone has to rebuild that list to match the new headings.

Finsweet Table of Contents closes that gap with a client-side script and two custom attributes. It reads the H2–H6 headings inside a Rich Text Block or Div Block and generates nested anchor links at runtime. Clicking a link scrolls smoothly to its section, and the active link picks up the native Current state as readers scroll. It is free and needs no external accounts or servers.

Freelancers and agencies reach for it on client hand-offs because the setup runs without ongoing maintenance. Content marketers get section navigation that regenerates with every CMS edit. It fits blogs, documentation sites, course pages, and resource libraries built on long-form Webflow content.

How to integrate Finsweet-table-of-contents with Webflow

What is Finsweet-table-of-contents? Finsweet Table of Contents is one of 28 solutions in Attributes, by Finsweet, a free library of features for Webflow sites configured through HTML custom attributes. It generates a table of contents from H2–H6 headings inside a Rich Text Block or Div Block, on static pages or CMS template pages. A single CDN-hosted script powers the whole library; there is no app to install and no account to create.

Teams add this integration when CMS articles run past a few screens and readers need a way to jump between sections. The same setup works on a static landing page or across an entire blog Collection template. This guide uses Attributes v2, the current version. The older v1 (Attributes Legacy) is outdated and no longer supported.

The Finsweet Table of Contents-Webflow integration supports two approaches:

  • Custom attributes with the universal script generate the table of contents and handle smooth scroll and active-state behavior without writing code.
  • The Finsweet Attributes callback API and Webflow's Data API give you programmatic control over initialization timing and CMS content, but require JavaScript or server-side development.

Most sites only need the attribute setup; the API path covers CMS timing edge cases and automated publishing.

Add the table of contents with custom attributes

Add one script to your head code, tag two elements with attributes, structure a link template, and publish. Most projects only need this path. Custom code requires a paid Site plan, so the free Starter plan cannot run the script. The full attribute reference lives in the Table of Contents documentation.

Install the universal script

The v2 script is shared across the whole Attributes library. Per Finsweet's docs, "you only need to include it once, even if you have multiple Attribute solutions on the page."

<script async type="module"
  src="https://cdn.jsdelivr.net/npm/@finsweet/attributes@2/attributes.js"
  fs-toc
></script>

To add the script:

  1. Copy the script tag above.
  2. Go to Site settings > Custom code, paste it into the Head code section, and click Save changes. See Custom code in head and body tags for both placement options.
  3. To load it on one page only, open that page's Page settings and paste the code into the Inside <head> tag section instead.

You can also paste the script into a Code Embed element on the canvas, though Finsweet's setup guide places it in the <head> tag.

Tag content and build the link template

Per the Finsweet docs, "All table of contents implementations must begin with the H2 element. It's not possible to start the table of contents with any heading level other than H2, such as H1 or H3." H1 is always ignored.

To configure the elements:

  1. Select the Rich Text Block or Div Block holding your content. Go to Element settings > Custom attributes, click the plus icon, and add fs-toc-element with the value contents.
  2. Add a Link Block, Text Link, or Text Block where the table of contents should render. Give it fs-toc-element with the value link.
  3. Structure the link templates by nesting: "Each Heading link template must be enclosed in a div wrapper, and this div wrapper should be a child of the div associated with the preceding Heading level."
  4. Set each link template's URL to the current page's URL, then style the green "Current" class in the Styles panel. Active-state highlighting needs no extra attributes.
  5. Publish the site.

Optional attributes and plain-text directives refine the output:

  • fs-toc-offsettop and fs-toc-offsetbottom accept any CSS value, such as 2rem, to control where the Current state activates under a sticky navbar.
  • fs-toc-hideurlhash="true" keeps heading IDs out of the URL during navigation.
  • fs-toc-instance="IDENTIFIER" on a common parent wrapper runs multiple independent tables of contents on one page.
  • [fs-toc-omit] typed as plain text before a heading excludes it from the table of contents.
  • [fs-toc-h#], such as [fs-toc-h4], changes a heading's level in the table of contents without changing it on the page.
  • fs-toc-element="ix-trigger" on a div inside a heading wrapper fires Webflow Interactions when a link becomes current or inactive.

One table of contents cannot span multiple content wrappers; per the docs, "This solution cannot be used to generate a single table of contents based on several Rich Text Elements." The Div Block method "will slightly remodel the HTML code of your page" by grouping each heading with its following content. This can affect layouts depending on the div's Display properties. Also plan to test on a published domain, since scripts do not run in Webflow's preview.

Build with the Webflow Data API and Finsweet callback functions

Finsweet Table of Contents has no REST API, webhooks, or server-side surface. Finsweet describes its Attributes API as an integration layer for the client-side Attributes solutions. Programmatic work therefore splits in two. Client-side JavaScript hooks into the library after it initializes, and Webflow's Data API manages the CMS content the table of contents reads.

Client-side callbacks handle initialization timing. Webflow's Data API handles CMS publishing.

Run code after the table of contents initializes

Community threads on the Finsweet forum report table of contents generation failing on CMS Rich Text pages even when the same setup works on static pages, possibly because the script runs before Webflow renders CMS content. Finsweet has published no official fix. Use the callback API as a practical workaround, documented in this forum thread.

To hook into initialization:

  1. Add this snippet to your page after the universal script:
window.fsAttributes = window.fsAttributes || [];
window.fsAttributes.push([
  'toc',
  (tocInstances) => {
    console.log('toc Successfully loaded!');
    // Add code here
  },
]);
  1. Place any dependent logic inside the callback, such as resetting Webflow Interactions with window.Webflow.require('ix2').init(), a pattern shown in this forum fix.
  2. For cases such as changing offsets between breakpoints, tear down and rebuild the instance:
window.fsAttributes.toc.destroy();
window.fsAttributes.toc.init();

The destroy-and-reinitialize pattern comes from a Finsweet forum solution. It is community-documented, not part of the official attribute reference.

Create CMS articles that render a table of contents

Content migrations and headless publishing pipelines can create the articles the table of contents reads. Once an item publishes, the attribute setup on the Collection template page renders the navigation client-side; no Finsweet-side call exists or is needed.

To publish an article via the API:

  1. Send POST https://api.webflow.com/v2/collections/{collection_id}/items with fieldData containing name, slug, and the Rich Text body field. This requires the CMS:write scope, per the Create Item reference.
  2. For migrations, POST https://api.webflow.com/v2/collections/{collection_id}/items/bulk accepts up to 100 items per request, per the bulk create reference.
  3. Publish with POST https://api.webflow.com/v2/collections/{collection_id}/items/publish and the returned item IDs, per the publish reference.

To act after publish, register a webhook for collection_item_published and trigger cache purges or search index updates from your own systems.

What can you build with the Finsweet Table of Contents Webflow integration?

These are working setups built on Finsweet Table of Contents in Webflow.

  • Blog posts with sticky section navigation: The Enhanced Table of Contents cloneable builds on Finsweet's solution with a sticky, expandable section on mobile so readers can jump between H2 sections at any scroll depth.
  • Documentation with hierarchical navigation: Finsweet's own Attributes docs site runs on the library and pairs generated navigation with accordion dropdowns plus keyword search and category filtering.
  • CMS article content menus: CMS Anchor Links v2 generates a section menu for longer blog articles from CMS-bound Rich Text, with no per-post setup after the template is tagged.
  • Course outlines and stacked-section pages: Course pages with lesson outlines work the same way, and instance identifiers let each stacked content block carry its own independent outline.

If you need more control over automated publishing and migration, the API integration path covers those cases with full flexibility.

Frequently asked questions

  • Yes. The integration depends on a script in your site's head code, and per the custom code documentation, "Custom code is a Site plan feature. To add custom code to your site, you'll need to upgrade to a paid Site plan." The free Starter plan cannot embed the script, so plan demos accordingly.

  • Because custom code and scripts only appear on the published site, per the Collection pages documentation. Publish to your webflow.io staging domain to test the generated links with smooth scrolling and Current-state styling before pushing to production.

  • Yes. The official documentation confirms fs-toc-element="contents" works on Rich Text Blocks, including CMS-connected ones, and on Div Blocks with direct heading children. One caveat comes from community reports rather than official docs: a Finsweet forum thread describes generation failing on CMS Rich Text pages when the same setup works on static pages, with no official resolution documented.

  • No. The tool runs entirely client-side with no API or webhooks, so Zapier and Make do not have a Finsweet connector. You can automate the Webflow CMS content the table of contents reads. The Zapier Webflow integration supports Webflow Create/Update Item and Webflow Create/Update Live Item actions, and Make's Webflow modules include Webflow Create Item and Webflow Get Collection among 40 modules. Zapier and Make connect to Webflow itself. They do not connect to Finsweet.

  • Use v2. Finsweet states that "Attributes Legacy will remain operational for existing projects, but please note that we have ceased offering support for this version." The two versions cannot run on the same page, though they can run on different pages of one site, which gives migrating teams a page-by-page path. Start new builds from the v2 Table of Contents guide, which includes the current script tag and full attribute reference.

Finsweet-table-of-contents
Finsweet-table-of-contents
Joined in

Description

Generates anchor link navigation from H2–H6 headings in Webflow Rich Text or Div Block content. Setup takes one script in your head code plus two custom attributes.

Install app

This integration page is provided for informational and convenience purposes only.


Other Plugins and integrations library integrations

Other Plugins and integrations library integrations

Cutcopy

Cutcopy

Connect CutCopy with Webflow to transfer variable collections and element attributes between sites without rebuilding them manually.

Plugins and integrations library
Learn more
MathJax

MathJax

Connect MathJax, an open-source math display engine, with Webflow to render LaTeX equations as typeset formulas with built-in accessibility, screen reader support, and cross-browser consistency.

Plugins and integrations library
Learn more
Awesome Table

Awesome Table

Connect Awesome Table with Webflow to display filterable Google Sheets data on any page without building a custom backend.

Plugins and integrations library
Learn more
Slater

Slater

Connect Slater with Webflow to write, test, and deploy custom JavaScript and CSS through a dedicated editor with staging environments, version history, and AI code generation.

Plugins and integrations library
Learn more
Clean Styles

Clean Styles

Connect Clean Styles with Webflow to find, merge, and organize duplicate CSS classes directly inside Webflow, keeping your class structure clean and maintainable.

Plugins and integrations library
Learn more
Impulse

Impulse

Connect Impulse with Webflow to add popups, gamification widgets, lead capture tools, and compliance banners to your site through a single marketplace app.

Plugins and integrations library
Learn more
Formly & Flowplay

Formly & Flowplay

Connect Formly and Flowplay with Webflow to enhance functionality without custom coding.

Plugins and integrations library
Learn more
Claritee

Claritee

Send approved Claritee wireframes into Webflow as editable layouts, then spend your time on styling instead of rebuilding sections.

Plugins and integrations library
Learn more
Flowbase Boosters

Flowbase Boosters

Add typewriter text, count-up stats, countdowns, and image sliders to Webflow with Flowbase Boosters: free attribute-driven scripts, no JavaScript to write.

Plugins and integrations library
Learn more

Related integrations

No items found.

Get started for free

Try Webflow for as long as you like with our free Starter plan. Purchase a paid Site plan to publish, host, and unlock additional features.

Get started — it’s free