A production-ready, mobile-first boilerplate for building immersive scrollytelling stories with SvelteKit, TailwindCSS, and Datawrapper.
This project was originally built for newsrooms but is adaptable for any storytelling need.
- Responsive Scrollytelling:
- Standalone Mode: Split-screen on desktop (Text left, Chart right), overlapping on mobile.
- Embed Mode: Full-width graphics with centered text overlay, perfect for CMS integration (iframe).
- Datawrapper Integration:
- Seamless
postMessagesupport for reactive charts. - Smart Preloading: Charts are kept in memory to prevent reloading/flickering during scroll.
- Seamless
- Theming: Easy customization via Tailwind tokens.
- Static Output: Builds to pure HTML/CSS/JS via
adapter-static.
npm installnpm run devnpm run buildThe output (in build/) can be hosted on any static server (S3, Vercel, Netlify, FTP).
If you are new to coding/github, here is the complete workflow to use this tool:
Open your terminal (Command Prompt on Windows, Terminal on Mac) and run:
git clone https://github.com/d-qn/scrollytelling.git
cd scrollytelling
npm install- Open the project in a code editor like VS Code.
- Go to
src/data/story.json. This is where you write your article. - For each step, create a chart in Datawrapper, publish it, and copy its ID (e.g.,
ABCDE). - Paste the ID into
"vizProps": { "chartId": "ABCDE" }.
Run this command to see your changes live in your browser (usually at http://localhost:5173):
npm run devWhen you are happy with the result, build the final files:
npm run buildThis creates a build/ folder. That's it. Thanks to relative path configuration, you can upload this folder anywhere (at the root or in a sub-directory), and it will work automatically.
- Hosting: Upload the contents of the
build/folder to your server. - CMS Integration: See
docs/WORKFLOW_CMS.mdfor details on how to embed the project.
Edit tailwind.config.js to match your brand identity. Keys usually start with theme-.
// tailwind.config.js
theme: {
colors: {
'theme-bg': '#ffffff', // Main background
'theme-primary': '#005578', // Main accent color
'theme-text': '#000000', // Body text
// ...
}
}- Install your font (e.g., via
@fontsource). - Update
src/routes/+layout.svelteto import the font file. - Update
src/app.cssto apply it globally.
The narrative is driven by src/data/story.json.
{
"format": "standalone", // or "embed"
"title": "My Story",
"steps": [
{
"content": "<h2>Step 1</h2><p>Description...</p>",
"vizType": "datawrapper",
"vizProps": {
"chartId": "ABCDE"
}
}
]
}datawrapper: Renders a Datawrapper chart by ID.image: Renders a full-screen image (srcprop).custom: Renders a generic placeholder (extensible inVizContainer.svelteto mapped Svelte components).
Released under the GNU GPLv3 license. You are free to use this for commercial purposes, but any modifications to the source code of this tool must be open-sourced if distributed.
See LICENSE for details.