Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/formsmd/formsmd/llms.txt

Use this file to discover all available pages before exploring further.

Slides enable you to create multi-step forms where users progress through one section at a time. Each slide can contain multiple form fields, content blocks, and navigation controls.

Overview

Forms.md uses slides to break long forms into manageable sections. Each slide:
  • Can contain multiple form fields and content
  • Has its own submit/next button
  • Can show progress indicators
  • Supports conditional display via jump conditions
  • Can post data incrementally
const composer = new Composer({ 
  page: "form-slides",
  slideDelimiter: "---" 
});

// First slide
composer.textInput("name", { question: "Your name?" });

// Create new slide
composer.slide({ pageProgress: "50%" });

// Second slide
composer.emailInput("email", { question: "Your email?" });

Creating slides

Use the slide() method to create a new slide:
src/composer.js
composer.slide({
  pageProgress: "50%",
  jumpCondition: "age >= 18",
  buttonAlignment: "center",
  post: true,
  disablePrevious: false
});

Slide parameters

pageProgress
string
Progress indicator shown at top (e.g., "50%" or "1/2")
jumpCondition
string
JavaScript expression that must evaluate to true for the slide to be shown
buttonAlignment
'start' | 'center' | 'end' | 'stretch'
Alignment of the slide’s CTA button
post
boolean
If true, posts form data up to this slide when going to the next one
disablePrevious
boolean
If true, disables the previous/back button on this slide

Slide types

Forms.md supports three types of slides: body slides, start slides, and end slides.

Body slides (default)

Regular slides containing form fields and content:
const composer = new Composer({ id: "survey" });

// First slide (default body slide)
composer.textInput("name", { 
  question: "What's your name?",
  required: true 
});

// Second slide
composer.slide({ pageProgress: "50%" });
composer.emailInput("email", { 
  question: "What's your email?",
  required: true 
});

Start slides

Create a welcome or intro slide with custom button text:
src/composer.js
composer.startSlide({
  buttonText: "Begin Survey",
  buttonAlignment: "center"
});

composer.free(`
# Welcome to our survey

This will take approximately 5 minutes to complete.
`);
Start slides can be the first slide or appear later in the form. They use special styling and button text.

End slides

Create a completion or thank you slide:
src/composer.js
composer.endSlide({
  redirectUrl: "https://example.com/thank-you"
});

composer.free(`
# Thank you!

Your response has been recorded.
`);
If you don’t explicitly create an end slide, Forms.md automatically generates a default one.

Page progress

Show users their progress through the form with progress indicators.

Percentage progress

Use percentage values to show progress:
src/slides-parse.js
composer.slide({ pageProgress: "25%" });
composer.slide({ pageProgress: "50%" });
composer.slide({ pageProgress: "75%" });
composer.endSlide();

Fraction progress

Use fractions for automatic percentage calculation:
src/slides-parse.js
composer.slide({ pageProgress: "1/4" });  // 25%
composer.slide({ pageProgress: "2/4" });  // 50%
composer.slide({ pageProgress: "3/4" });  // 75%
composer.endSlide();
Fractions are automatically converted to percentages using CSS calc(), so "1/4" becomes calc(100% * (1/4)).

Global progress control

Control progress indicator globally via settings:
const composer = new Composer({
  pageProgress: "show"  // "show" | "hide" | "decorative"
});
Or via Formsmd options:
const formsmd = new Formsmd(template, container, {
  pageProgress: "decorative"  // Progress bar that doesn't update
});

Slide navigation

Users navigate between slides using buttons in the slide and/or footer.

Slide control buttons

Each slide has a next/submit button. Control visibility globally:
const composer = new Composer({
  slideControls: "show"  // "show" | "hide"
});
The footer shows previous/next buttons:
const formsmd = new Formsmd(template, container, {
  slideControls: "show",
  footer: "show"
});

Disabling previous button

Prevent users from going back on specific slides:
src/composer.js
composer.slide({
  disablePrevious: true
});

Incremental form submission

Post form data incrementally as users progress through slides:
const composer = new Composer({
  postUrl: "/api/save-progress"
});

// Slide 1: Basic info
composer.textInput("name", { question: "Name?", required: true });
composer.emailInput("email", { question: "Email?", required: true });

// Slide 2: Will post slide 1 data when advancing
composer.slide({ 
  post: true,
  pageProgress: "50%" 
});

composer.choiceInput("plan", {
  question: "Select a plan",
  choices: ["Basic", "Pro", "Enterprise"],
  required: true
});
The post parameter only works on slides that are part of a form (page type "form-slides") and contain at least one form field.

Complete example

import { Composer, Formsmd } from "formsmd";

const composer = new Composer({
  id: "onboarding",
  title: "User Onboarding",
  postUrl: "/api/onboard",
  pageProgress: "show"
});

// Start slide
composer.startSlide({ 
  buttonText: "Get Started",
  buttonAlignment: "center" 
});
composer.free(`
# Welcome!

Let's set up your account in a few easy steps.
`);

// Slide 1: Personal info
composer.slide({ pageProgress: "33%" });
composer.textInput("fullName", {
  question: "What's your full name?",
  required: true
});
composer.emailInput("email", {
  question: "What's your email?",
  required: true
});

// Slide 2: Company info
composer.slide({ 
  pageProgress: "66%",
  post: true  // Save progress
});
composer.textInput("company", {
  question: "Company name?"
});
composer.selectBox("companySize", {
  question: "Company size?",
  options: ["1-10", "11-50", "51-200", "201+"],
  required: true
});

// Slide 3: Preferences
composer.slide({ pageProgress: "100%" });
composer.choiceInput("interests", {
  question: "What are you interested in?",
  choices: ["Marketing", "Sales", "Support", "Engineering"],
  multiple: true
});

// End slide
composer.endSlide();
composer.free(`
# All set!

Your account has been created successfully.
`);

const formsmd = new Formsmd(
  composer.template,
  document.getElementById("container"),
  { saveState: true }
);
formsmd.init();

Slide templates

Behind the scenes, slides are parsed using templates defined in src/slides-parse.js. Each slide type (form/div, start, end) has its own template structure.

Slide template structure

src/slides-parse.js
// Form slide with submit button
<form class="fmd-slide fmd-first-slide" data-fmd-page-progress="50%">
  <div class="fmd-grid">
    {content}
    <div class="fmd-next-controls">
      <button type="submit" class="fmd-submit-btn">Submit</button>
    </div>
  </div>
</form>

// Non-form slide with next button
<div class="fmd-slide" data-fmd-jump="condition">
  <div class="fmd-grid">
    {content}
    <div class="fmd-next-controls">
      <button type="button" class="fmd-next-btn">Next</button>
    </div>
  </div>
</div>

Programmatic navigation

Use Formsmd methods to control slides programmatically:
const formsmd = new Formsmd(template, container);
formsmd.init();

// Get current active slide
const activeSlide = document.querySelector(".fmd-slide.fmd-active-slide");

// Go to next slide
formsmd.nextSlide(activeSlide);

// Go to previous slide
formsmd.prevSlide(activeSlide);

// Get next slide (respects jump conditions)
const { slide, index } = formsmd.getNextSlide();

// Get previous slide (respects jump conditions)
const { slide, index } = formsmd.getPrevSlide();

Best practices

1

Keep slides focused

Each slide should have a single purpose or related group of fields. Don’t overcrowd slides.
2

Show progress

Always use pageProgress on multi-step forms to help users understand how much is left.
3

Save progress incrementally

Use post: true on important slides to save user progress and prevent data loss.
4

Use start slides

Add a start slide to explain the form’s purpose and estimated completion time.
5

Consider mobile

Test slide navigation on mobile devices. Footer buttons are especially important for small screens.

Next steps

Conditional logic

Add dynamic slide behavior with jump conditions

Composer

Learn more about building templates

Formsmd

Explore rendering and initialization options