Resources
Jul 13, 2025

Dynamic Charts in Webflow: CMS-Powered Chart.js Visualisations (2025 Tutorial)

Learn to output JSON from Collection Lists, feed it into Chart.js, and style accessible, performant charts that auto-update when editors change CMS items.

Dynamic Charts in Webflow: CMS-Powered Chart.js Visualisations (2025 Tutorial)

Published July 2025 • 10 min read

Why native charts matter

SaaS dashboards, annual reports and fintech landing pages scream for data visualisation, but screenshots of Excel feel 2010. Until 2024 most Webflow users embedded Google Sheets charts (slow) or Iframes from Tableau (heavy). Thanks to inline <canvas> support and the lightweight Chart.js 4, you can render crisp, responsive graphs that update whenever editors tweak CMS items—no code export or rebuild required.

1 — Prepare your CMS collection

Create a collection called Metrics with fields:

  • Name (Plain text: e.g. Monthly Revenue)
  • Labels (Rich text or Plain text, comma-separated months)
  • Data Points (Plain text: comma list 12000,14500,16000…)
  • Colour (Color)

One item = one dataset in Chart.js. Editors can add new items without touching code.

2 — Output JSON with a hidden Collection List

<div id="chartData" style="display:none">
  <div class="metric-item" fs-cmsitem="">
    <span class="metric-labels">{{labels}}</span>
    <span class="metric-data">{{data-points}}</span>
    <span class="metric-colour" style="background:{{colour}}"></span>
  </div>
</div>

Webflow will repeat .metric-item for each CMS row on publish.

3 — Add the canvas element

Place a <canvas id="myChart" width="800" height="400"></canvas> where you want the graph. Give the wrapper position:relative and set canvas to width:100% for responsiveness.

4 — Include Chart.js (tree-shaken)

Add to Site Settings → Custom Code → <head>:

<script type="module">
import { Chart, BarController, BarElement, CategoryScale, LinearScale, Tooltip } from 'https://cdn.jsdelivr.net/npm/chart.js@4.5.1/+esm';
Chart.register(BarController, BarElement, CategoryScale, LinearScale, Tooltip);
window.Chart = Chart;
</script>

Only 14 kB after gzip—much lighter than full bundle.

5 — Parse CMS data & render

<script>
const items = [...document.querySelectorAll('.metric-item')].map(el => ({
  labels: el.querySelector('.metric-labels').textContent.split(','),
  data:   el.querySelector('.metric-data').textContent.split(',').map(Number),
  colour: getComputedStyle(el.querySelector('.metric-colour')).backgroundColor
}));
const datasets = items.map(i => ({
  label: i.label || 'Dataset',
  data: i.data,
  backgroundColor: i.colour
}));
new Chart(document.getElementById('myChart'), {
  type: 'bar',
  data: { labels: items[0].labels, datasets },
  options: { responsive:true, plugins:{ tooltip:{ callbacks:{ label:ctx => `$${ctx.parsed.y.toLocaleString()}` } } } }
});
</script>

The script reads hidden DOM nodes, so editors can change numbers in the Webflow Editor and republish—chart updates instantly.

6 — Add animations & theme support

Chart.js respects CSS variables. Tie backgroundColor to your --primary-500 Variable or switch palettes on [data-theme='dark'] attribute for seamless dark-mode support.

7 — Accessibility & performance tips

  • Add role="img" aria-label="Bar chart of monthly revenue" to the canvas.
  • Lazy-load heavy datasets by wrapping script in requestIdleCallback.
  • For multi-page sites, import Chart.js only on pages that include #myChart.

8 — Bonus: Live update without republish

Need real-time data? Use Webflow’s CMS Webhooks (Item Updated) → Netlify Function → Pusher / Socket.io to push new JSON to the page and call chart.update()—no refresh required.

Conclusion

With a few lines of ES modules and clever CMS markup, Webflow can power fully-dynamic, responsive charts—perfect for SaaS metrics, startup pitch decks or interactive landing pages. No React, no heavy libs; just native Chart.js and the CMS you already love.

Subscribe to our weekly newsletter

Lorem ipsum dolor sit amet consectetur mi urna tellus dignissim duis at in tempor mauris morbi fermentum dolor lobortis aliquam maecenas.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Subscribe Newsletter Image - Subscription X Webflow Template