@gemeosagency/webflow-multistep-form
v0.1.1
Published
Lightweight, accessible multistep form solution for Webflow with smooth transitions, smart validation, conditional navigation, and progress bar
Downloads
31
Readme
Webflow Multistep Form
A lightweight, accessible multistep form solution for Webflow using custom attributes. Features smooth fade transitions, automatic next button disable/enable, conditional navigation, and an optional progress bar.
Features
✨ Multiple forms per page - Each form is independently scoped
🎨 Smooth transitions - Fade in/out between steps
✅ Smart validation - Next button auto-disables when required fields are empty
🔀 Conditional navigation - Jump to specific steps based on user input
📊 Progress bar - Optional visual progress indicator
♿ Accessible - Proper ARIA attributes and focus management
Quick Start
1. Installation
Add the script to your Webflow project's Site Settings > Custom Code > Footer Code:
<script src="https://cdn.jsdelivr.net/npm/@gemeosagency/webflow-multistep-form@latest/dist/index.js"></script>Or use the CSS if needed:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gemeosagency/webflow-multistep-form@latest/dist/styles.css">2. Structure your form in Webflow
Basic structure:
Div Block [data-form="multistep"] ← Form wrapper
├── Div Block [data-form="step"] ← Step 1
│ ├── Input (required)
│ ├── Button [data-form-button="next"]
├── Div Block [data-form="step"] ← Step 2
│ ├── Input (required)
│ ├── Button [data-form-button="prev"]
│ ├── Button [data-form-button="next"]
└── Div Block [data-form="step"] ← Step 3 (final)
├── Textarea (required)
├── Button [data-form-button="prev"]
└── Button type="submit" ← Native submitWith progress bar:
Div Block [data-form="multistep"]
├── Div Block [data-form="progress"] ← Progress container
│ └── Div Block [data-form="progress-bar"] ← Progress fill
├── Div Block [data-form="step"] ...
└── ...3. Add custom attributes
In Webflow Designer, select each element and add custom attributes:
| Element | Attribute | Value | Description |
|---------|-----------|-------|-------------|
| Form wrapper | data-form | multistep | Identifies the multistep form |
| Step container | data-form | step | Each step block |
| Next button | data-form-button | next | Navigate to next step |
| Previous button | data-form-button | prev | Navigate to previous step |
| Submit button | - | - | Native submit (last step) |
| Progress container | data-form | progress | Optional progress bar wrapper |
| Progress fill | data-form | progress-bar | Optional progress bar fill |
Optional: Named steps for conditional navigation
Div Block [data-form="step"] [data-form-step="final"] ← Named step
Button [data-form-button="final"] ← Jumps to "final" stepExamples
Basic 3-step form
Webflow structure:
- Create a div with
data-form="multistep" - Inside, create 3 divs with
data-form="step" - Add form fields in each step
- Add buttons with
data-form-button="next"anddata-form-button="prev"
With conditional logic
For a form where users can skip to the end based on their answer:
Step 1:
Input: "Do you need assistance?"
Button [data-form-button="yes"] → Goes to step 2
Button [data-form-button="final"] → Jumps to final stepStep 2: (named with data-form-step="yes")
Input: "Describe your needs"
Button [data-form-button="next"]Final step: (named with data-form-step="final")
Textarea: "Additional comments"
Submit buttonWith progress bar
- Create a div with
data-form="progress"(inside or outside the form wrapper) - Inside, create a div with
data-form="progress-bar" - Style the progress bar in Webflow:
- Container: background color (e.g., light gray)
- Fill: background color (e.g., primary color), width starts at 0%
The script will automatically update the width to show progress.
Styling
Default fade transitions
The script includes fade transitions (300ms). Steps have these classes:
.data-form-step--visible- Currently visible step.data-form-step--hidden- Hidden step.data-form-step--fade-out- Step fading out
You can customize the transition duration in your Webflow custom CSS:
[data-form="step"] {
transition: opacity 0.5s ease; /* Change duration */
}Progress bar styling
Style directly in Webflow Designer:
- Container: Set background, height, border-radius
- Fill: Set background color (width is controlled by the script)
The script sets both width and --progress CSS variable for flexibility.
Attributes Reference
Form wrapper
data-form="multistep"- Identifies the multistep form container
Steps
data-form="step"- Regular step (order = DOM order)data-form-step="[name]"- Named step for conditional navigation
Buttons
data-form-button="next"- Go to next step (auto-disabled when required fields empty)data-form-button="prev"- Go to previous stepdata-form-button="[name]"- Go to step withdata-form-step="[name]"
Programmatic navigation (API)
Depuis un autre script ou un bouton hors formulaire, tu peux changer de step avec l’API exportée :
Par index (0-based) :
import { goToStep } from '@gemeosagency/webflow-multistep-form'
const form = document.querySelector('[data-form="multistep"]')
goToStep(form, 0) // premier step
goToStep(form, 2) // troisième stepPar nom du step (data-form-step) :
import { goToStepByName } from '@gemeosagency/webflow-multistep-form'
const form = document.querySelector('[data-form="multistep"]')
goToStepByName(form, 'contact') // va au step avec data-form-step="contact"
goToStepByName(form, 'final')Exemple : bouton externe qui envoie vers un step précis
Avec modules (si tu bundles la lib) :
import { goToStep } from '@gemeosagency/webflow-multistep-form'
const form = document.querySelector('[data-form="multistep"]')
document.getElementById('go-to-step-2').addEventListener('click', () => {
if (form) goToStep(form, 1)
})Avec script chargé par balise (Webflow custom code, après le script du formulaire) :
// goToStep / goToStepByName sont exposés sur window
const form = document.querySelector('[data-form="multistep"]')
document.getElementById('go-to-step-2').addEventListener('click', () => {
if (form && window.goToStep) window.goToStep(form, 1)
})
// ou par nom : window.goToStepByName(form, 'contact')Progress bar (optional)
data-form="progress"- Progress bar containerdata-form="progress-bar"- Progress bar fill element
Validation
The script automatically handles validation:
- Next button is disabled when any required field in the current step is empty
- Supports
input[required],select[required],textarea[required] - Handles checkboxes and radio buttons correctly
- Real-time validation on
inputandchangeevents
To make a field required, check "Required" in Webflow's field settings.
Browser Support
Modern browsers with ES6+ support:
- Chrome, Edge, Firefox, Safari (latest versions)
- Mobile browsers (iOS Safari, Chrome Mobile)
Development
Local setup
pnpm install
pnpm dev # Development mode with live reload at http://localhost:3000Testing on Webflow during development
To load your local script in Webflow, you need to expose your local server via a tunnel (browsers block localhost access from HTTPS sites):
Option 1: Using ngrok (recommended)
- Install ngrok: https://ngrok.com/download
- In a new terminal:
ngrok http 3000 - Copy the HTTPS URL (e.g.,
https://abc123.ngrok.io) - In Webflow Custom Code:
<script src="https://abc123.ngrok.io/index.js"></script>
Option 2: Using Cloudflare Tunnel
- Install cloudflared: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/
- In a new terminal:
cloudflared tunnel --url http://localhost:3000 - Use the provided URL in Webflow
Build
pnpm build # Production build
pnpm test # Run tests
pnpm lint # Check code qualityDebug Mode
By default, the script runs silently (no console logs). If something isn't working, enable debug mode:
Option 1: Add ?debug=multistep to URL
Visit your page with: https://your-site.webflow.io/?debug=multistep
This automatically enables verbose logging in console:
- Number of forms found
- Steps per form
- Detected buttons
- Required fields
- Progress bar configuration
Option 2: Browser console
Open console (F12) and type:
debugMultistepForms()Option 3: Enable programmatically
In console or before loading the script:
window.WEBFLOW_MULTISTEP_DEBUG = trueDebug logs (when enabled)
In debug mode, the script shows logs for:
- Initialization:
✅ Webflow Multistep: Initializing X form(s) - Button registration:
🔘 Button registered: [data-form-button="next"] - Clicks:
👆 Button clicked: [data-form-button="next"] - Navigation:
➡️ Navigating to next step
Troubleshooting
Nothing happens when clicking "Next":
- Open console (F12) and check logs
- If no "Button clicked" log → button doesn't have
data-form-button="next"attribute - If "Button clicked" log but no navigation → verify steps have
data-form="step" - Run
debugMultistepForms()in console to see configuration
Next button not disabling:
- Check that fields have the
requiredattribute - Verify the button has
data-form-button="next"
Steps not transitioning:
- Check that each step has
data-form="step" - Ensure CSS transitions are not overridden
Progress bar not updating:
- Verify
data-form="progress"on container - Verify
data-form="progress-bar"on fill element - Check that the form wrapper has
data-form="multistep"
Conditional navigation not working:
- Ensure target step has
data-form-step="[name]" - Ensure button has
data-form-button="[name]"with matching name - Both must be in the same form wrapper
Skipped steps and required fields
When you skip steps (e.g. bouton vers l’étape « final »), les étapes non visitées peuvent contenir des champs required. Pour éviter que la validation native du navigateur bloque l’envoi, le script retire temporairement l’attribut required sur les champs des steps cachés et le remet quand l’utilisateur revient sur ce step. Tu peux donc avoir des steps avec required tout en autorisant un parcours conditionnel sans bug à l’envoi.
License
ISC
