Internal Framework Documentation

BX Webflow Framework

A barebones, component-first Webflow starter. Custom (Client-First style) class naming, a self-contained per-section script system, an optional smart vendor loader, and full Cursor + Claude Code tooling. Everything beyond the cloneable is optional.

Webflow-native AI-ready Component-first Self-contained scripts Standalone cloneable

01 · Philosophy

Why it's built this way

Webflow ships per-page CSS, so utility-class frameworks lose most of their payoff while adding composition overhead. This template leans on semantic, component-scoped classes instead — clear to read, easy to map to Figma, and simpler for AI to set properties on without recalling token soup.

The cloneable is fully standalone. Use it as a plain Webflow starter with no repo and no AI tooling. The folder structure, section scripts, vendor loader, and AI skills are all opt-in.
Component-first classes
Custom classes scoped to their component (blog_, hero_) — self-explanatory, no practical limits.
Self-contained sections
Each section keeps its own script and its own scoped CSS classes — no utility classes. Webflow's per-page CSS strips unused classes from each page's stylesheet, so unused weight never ships. Clients can move or delete a section without breaking the page.
Load only what's used
Shared libraries load once per page, with only the modules sections on that page actually request.
AI-aware structure
Scripts carry a fixed preamble so AI knows when to touch globals, share a vendor, or keep code local.
02 · Naming & Classes

Classes, containers & structure

Client-First with a few tweaks: the component name comes first, element parts follow, separated by underscores (hyphens inside multi-word names).

Section wrapper
.[component]_section instead of a generic .section — e.g. .blog-slider_section.
Inner element
.[component]_[element] — e.g. .product-card_image_wrap.
Global utilities
Always pair with a custom class: .element_contain.container-medium, not a bare .container-medium.
Section padding
Global padding sits on the section element via the class attribute, so you can drop it when nesting a section (inside a dialog, split page, etc.).

Typical section structure

.element_section.padding-global
├── .section-css   # per-section CSS embed
├── {{Spacer Component}}
├── .element_contain.container-medium
│   └── .element_layout
├── {{Spacer Component}}
└── .section-js    # per-section JS embed (paste minified script here)
03 · Data Attributes

Three wiring patterns

Markup hooks always use the data- prefix and the Client-First word pattern: data-{middle}-{facet}="{value}". Pick the pattern that matches what you're marking.

1 · Named piece
Label a block inside a section. Middle is the section name, ends in el; value names the block.
data-split-page-el="content"
2 · Shared behaviour
Link several elements to one thing via a topic + role and a repeated id.
data-dialog-open="hero" ↔ data-dialog-id="hero"
3 · Animation
Point an element at a named animation preset.
data-anim-el="fade-up"
04 · Section Scripts

Modular section & component scripts

Each section or component owns one script, pasted into its .section-js / .component-js embed. Scripts are idempotent, multi-instance safe, and declare their own namespace window.bx_[component]. Shared libraries are requested through the dispatcher — never loaded with a raw <script> tag.

project_section_hero-slider.js — Swiper via the dispatcher
/*! 13/03/26 v1 hero-slider: Swiper nav + pagination, A11y */
(() => {
  const ns = 'bx_hero-slider';
  if (!window[ns]) window[ns] = { instances: new Map() };

  // Declare what this section needs; the loader unions all
  // requests on the page and loads each library once.
  window.bx_vendors.swiper.request(
    ['Navigation', 'Pagination', 'A11y'],
    initHeroSlider,
    { priority: true } // above-the-fold → load immediately
  );

  function initHeroSlider() {
    // query .hero-slider_section, init each .swiper once
  }
})();

Every code/sections/*.js and code/components/*.js file opens with a fixed three-part preamble:

  • Banner — one /*! … */ line: date, version, name, one-line summary (survives minification).
  • Description — what it does, DOM/classes, vendors, a11y, and any script-only data-* state.
  • Data attributes — the author-facing data-* hooks you wire up in Webflow.
The pattern is written for AI to follow. docs/COMPONENT_SCRIPT_PATTERN.md is the canonical spec for preambles, the dispatcher, and dependency-loading decisions — phrased so an agent can read it and scaffold a brand-new, on-pattern section script for you. This repo is a ready-made sample project: open it in Cursor or Claude Code and the rules + pattern doc are already wired in, so “build me a blog slider section” produces a script that matches everything else here.

Minification & comments

Full source files are encouraged to be heavily commented — the three-part preamble plus inline notes are what let an agent understand a script's behaviour and safely extend it. You ship the minified version: a Cursor minification plugin generates a -min companion for each file (e.g. project_section_faq-min.js), and that’s what goes into the Webflow embed. Never edit the -min files by hand — they’re regenerated from source.

05 · Vendor Loader

Smart shared vendor dispatcher

The default head snippet only creates an empty window.bx_vendors object, so the framework stays optional. Enable the presets a project needs in code/global/src/project_global_vendors.js, minify, and paste over the placeholder. Sections then request() what they need; the dispatcher collects every declaration and loads each library once per page with the union of requested modules.

swiper
request(modules, cb, { priority }) — structured modules, unioned per page. priority: true bypasses the batch for above-the-fold heroes (Swiper only).
finsweet
request(flags, cb) — Finsweet Attributes v2; fs-* flags applied before load. No priority mode.
finsweetV1
request(['accordion', 'a11y']) — v1 standalone packages, one load per page.
external
external(url, { async }) — any one-off script; dedupes by URL, returns a Promise.

If no section requests a library on a page, nothing loads for it — zero cost. GSAP is supplied by Webflow when Interactions need it; don't add a GSAP loader, feature-detect window.gsap instead.

Prefer not to use it? You can always drop a library’s <script> straight into a page’s custom code and init it yourself — the loader is optional. But the dispatcher exists for a reason: a single deduplicated load per page, only the modules each page needs, and modular sections that stay self-contained. For optimal performance and portability, the vendor script is the better default.

Like section scripts, the dispatcher follows docs/COMPONENT_SCRIPT_PATTERN.md. Working in the sample project with Cursor or Claude Code, you can just ask the agent to enable a preset (Swiper, Finsweet, …) or add a new one — it edits project_global_vendors.js on-pattern and reminds you to re-minify into the head snippet.
06 · Core Components

Shipped components & their data hooks

Drop-in scripts that live in code/components/ and code/sections/. Expand each for what it does and the markup hooks it reads — click any attribute to copy it.

07 · Repo Structure

Folder structure

Scripts stay close to what they belong to. Readable source lives in the repo; you minify and paste the output into Webflow.

ProjectName/
├── .cursor/           # Cursor rules, agents, skills
│   ├── rules/  agents/  skills/
│   └── mcp.json        # project MCP config (Webflow)
├── .claude/           # Claude Code agents + skills
├── CLAUDE.md           # Claude project instructions
├── assets/            # cms/ · meta/ · pages/
├── code/
│   ├── global/         # head, body, styles (+ src/ for vendor source)
│   ├── sections/       # per-section scripts
│   └── components/     # dialog, video, …
├── docs/              # this doc + COMPONENT_SCRIPT_PATTERN.md
├── fonts/
└── tools/
08 · AI Skills

Project-level AI skills

Shipped for both Cursor (.cursor/skills/) and Claude Code (.claude/skills/). The AI reads them when relevant or when you @-mention them.

01
project-start
One-shot template bootstrap after copying: asks for a project slug, renames all project_* files to <slug>_*, find-replaces the placeholder in docs/rules/Claude setup, then deletes itself.
Core
02
figma-variables-to-webflow
Ports local Figma variables into a Webflow site's variable collections using the BX primitives-vs-tokens structure. Needs Figma MCP + Webflow Designer MCP.
Core
03
figma-text-sizes-to-webflow
Creates Webflow text-size utility classes and heading-style classes from Figma local text styles, with matching Style Guide samples. Use variables or classes — your call.
Core
04
webflow-component-instances
Places component instances on a page or in slots and sets instance prop overrides from Figma or specs, while avoiding Designer MCP hangs. For building pages from existing components.
Needs MCP
05
webflow-cloudinary-images
Uploads local images to Cloudinary and sets their URLs on Webflow CMS image fields — bulk image population for collections. Needs Webflow + Cloudinary MCPs.
Needs MCP
06
ffmpeg-compress-images
Batch-compresses JPEG/PNG in a folder to WebP (libwebp, q75) and optionally renames to the asset convention. Never touches SVGs. Needs FFmpeg installed.
Optional
09 · Tooling

Editors & rules

Cursor and Claude Code share the same rules — Cursor via .cursor/, Claude Code via CLAUDE.md + .claude/. Rules cover the section-script pattern, accessibility, asset naming, never editing minified output, and Webflow/Figma setup.

Cursor
Smoothest UX for MCP + plugin management. First choice for most workflows.
Claude Code
Fully supported via CLAUDE.md; rules and skills are mirrored. Strong for agentic runs.
Webflow MCP
Project-scoped in .cursor/mcp.json. Authorize only the current site; launch the MCP Bridge App in Designer for Designer-level tools.
10 · Quick Start

Using the cloneable

Cloneable only
Clone in Webflow, delete what you don't need. Light/dark mode, variables, base classes and components are all included — no repo required.
+ Repo & AI
Add the repo, run /project-start, then the section-script system, vendor loader, AI skills and asset pipeline are at your disposal.
This whole page is a single Webflow embed scoped under .bx-docs. Delete that one embed when you start a real project — nothing else depends on it.

BX Webflow Framework · internal use · built at BX Studio