Building a component
This tutorial walks through building a component (module) from scratch — structure, logic, styling, and wiring it to Webflow.
What you’ll build
Section titled “What you’ll build”A counter module: a simple interactive element with increment/decrement buttons and a display. It demonstrates the module pattern, DOM wiring, lifecycle hooks, and styling.
Prerequisites
Section titled “Prerequisites”- A project created in Ssscript (Quick start if needed).
- Basic familiarity with the editor.
Step 1 — Create the module file
Section titled “Step 1 — Create the module file”In Code view (⌘2 / Ctrl+2), right-click the src/modules/ folder in the file tree and choose New File. Name it counter.ts.
Every module exports a default function that receives the DOM element and its dataset:
export default function (element: HTMLElement, dataset: DOMStringMap) { // Module logic goes here}The module auto-mounts on any HTML element with data-module="counter".
Step 2 — Add the logic
Section titled “Step 2 — Add the logic”Replace the file contents with:
import { onDestroy } from "@/modules/_";
export default function (element: HTMLElement, dataset: DOMStringMap) { const display = element.querySelector( "[data-counter-display]", ) as HTMLElement | null; const increment = element.querySelector( "[data-counter-increment]", ) as HTMLElement | null; const decrement = element.querySelector( "[data-counter-decrement]", ) as HTMLElement | null;
let count = parseInt(dataset.counterStart ?? "0", 10);
function update() { if (display) display.textContent = String(count); }
function handleIncrement() { count++; update(); }
function handleDecrement() { count--; update(); }
increment?.addEventListener("click", handleIncrement); decrement?.addEventListener("click", handleDecrement); update();
onDestroy(() => { increment?.removeEventListener("click", handleIncrement); decrement?.removeEventListener("click", handleDecrement); });}The module:
- Queries child elements using
data-*attributes. - Reads an initial value from
data-counter-start(optional). - Listens for clicks and updates the display.
- Cleans up event listeners on destroy (important for page transitions).
Step 3 — Style it
Section titled “Step 3 — Style it”Open src/styles/app.css and add styles. Only use app.css for CSS that Webflow can’t handle — in most cases, layout and typography should live in Webflow classes. For this example, add minimal animation CSS:
[data-module="counter"] [data-counter-display] { transition: transform 0.15s ease-out;}
[data-module="counter"] [data-counter-display].bumped { transform: scale(1.1);}Then update the module to toggle the class briefly on change:
function update() { if (display) { display.textContent = String(count); display.classList.add("bumped"); setTimeout(() => display.classList.remove("bumped"), 150); }}Step 4 — Wire the HTML in Webflow
Section titled “Step 4 — Wire the HTML in Webflow”In your Webflow site, create the DOM structure that the module expects. You can do this manually in the Designer or use the @@webflow agent mode if you have Webflow MCP connected.
The required structure:
<div data-module="counter" data-counter-start="0"> <button data-counter-decrement>-</button> <span data-counter-display>0</span> <button data-counter-increment>+</button></div>Key attributes:
data-module="counter"— tells the module system to mountsrc/modules/counter.tson this element.data-counter-start— optional initial value.data-counter-display,data-counter-increment,data-counter-decrement— child selectors the module uses.
Step 5 — Run and test
Section titled “Step 5 — Run and test”Open the terminal (⌘J) and click Run to start the dev server. Open http://localhost:6454 in your browser (or check the embedded preview if your Webflow site loads the dev URL).
Click the buttons and verify the counter increments and decrements with the scale animation.
Using AI to build modules
Section titled “Using AI to build modules”You can also ask the AI to build modules for you. Try:
@@build Create a scroll-triggered fade-in module that animates elements into view when they enter the viewportThe agent follows the same module pattern — creating the file in src/modules/, using lifecycle hooks, and providing a Webflow DOM handoff with the required data-* attributes.
- Deploy & embed — Publish your project and embed it in Webflow.
- Embedding in Webflow — Where to paste the embed snippets.
- Starters — Learn what’s inside a starter template.