# Installation and usage
**Forms.md** (formerly Blocks.md) lets you build powerful multi-step forms and surveys with minimal code. Create production-ready forms that are privacy-focused, accessible, localizable, and themeable. Perfect for user onboarding, data collection, customer feedback, and much more.
***
## Installation
### Install via npm
```
npm install formsmd
```
### Use in browser
Download the distribution files from [the GitHub repo](https://github.com/formsmd/formsmd). Include the files using `` and `
```
***
## Usage
Create forms programmatically using the `Composer` class, then initialize them with the `Formsmd` class by passing in the template.
{% tabs %}
{% tab title="With composer" %}
```javascript
import "formsmd/dist/css/formsmd.min.css"; // Or import formsmd.rtl.min.css in case of RTL
import { Composer, Formsmd } from "formsmd";
// Create form with ID and submission endpoint
const composer = new Composer({
id: "onboarding-form",
postUrl: "/api/onboard"
});
// Choice input for position
composer.choiceInput("position", {
question: "What's your position?",
choices: ["Product Manager", "Software Engineer", "Founder", "Other"],
required: true
});
// Text input if user selects "Other" position
composer.textInput("positionOther", {
question: "Other",
required: true,
labelStyle: "classic",
displayCondition: {
dependencies: ["position"],
condition: "position == 'Other'"
}
});
// Start new slide, progress indicator at 50%
composer.slide({
pageProgress: "50%"
});
// Choice input for how user discovered the product
composer.choiceInput("referralSource", {
question: "How did you hear about us?",
choices: ["News", "Search Engine", "Social Media", "Recommendation"],
required: true
});
// Start new slide, show only if user was recommended, progress indicator at 75%
composer.slide({
jumpCondition: "referralSource == 'Recommendation'",
pageProgress: "75%"
});
// Email input for recommender email address
composer.emailInput("recommender", {
question: "Who recommended you?",
description: "We may be able to reach out to them and provide a discount for helping us out."
});
// Initialize with template, container, and options
const formsmd = new Formsmd(
composer.template,
document.getElementById("onboarding-form-container"),
{
postHeaders: {
Authorization: `Bearer ${localStorage.getItem("token")}`
}
}
);
formsmd.init();
```
{% endtab %}
{% tab title="Markdown-like" %}
```javascript
import "formsmd/dist/css/formsmd.min.css"; // Or import formsmd.rtl.min.css in case of RTL
import { Formsmd } from "formsmd";
// Create template
const template = `
#! id = onboarding-form
#! post-url = /api/onboard
position* = ChoiceInput(
| question = What's your position?
| choices = Product Manager, Software Engineer, Founder, Other
)
::: [{$ position $}]
{% if position == "Other" %}
positionOther* = TextInput(
| question = Other
| labelStyle = classic
)
{% endif %}
:::
---
|> 50%
referralSource* = ChoiceInput(
| question = How did you hear about us?
| choices = News, Search Engine, Social Media, Recommendation
)
---
-> referralSource == "Recommendation"
|> 75%
recommender = EmailInput(
| question = Who recommended you?
| description = We may be able to reach out to them and provide a discount for helping us out.
)
`;
// Initialize with template, container, and options
const formsmd = new Formsmd(
template,
document.getElementById("onboarding-form-container"),
{
postHeaders: {
Authorization: `Bearer ${localStorage.getItem("token")}`
}
}
);
formsmd.init();
```
{% endtab %}
{% endtabs %}
Slide 1 when "Other" is picked
Slide 2
Slide 3 (only shown if the user was recommended)
***
## Form settings
The `Composer` constructor accepts an object called `settings` as the argument. These are called form settings, and they can be used to configure various aspects of the form.
```typescript
constructor(settings: object)
```
### Example
```javascript
const composer = new Composer({
formStyle: "classic",
id: "my-form",
postUrl: "/api/endpoint",
});
```
Generates the following Markdown-like syntax:
```
#! form-style = classic
#! id = my-form
#! post-url = /api/endpoint
```
### Arguments
| Name | Type | Description |
| ---------- | -------- | ------------------------------------------------------ |
| `settings` | `object` | Object containing configuration settings for the form. |
### Settings parameters
{% tabs %}
{% tab title="With composer" %}
{% hint style="warning" %}
The `formsmdBranding` and/or `footer` parameters can only be set to `"hide"` if your site has a [Pro subscription](https://forms.md/pricing/) (or above).
{% endhint %}
The `settings` argument can contain the following parameters:
| Name | Type | Description |
| ------------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `autofocus` | `"all-slides"` | If set to `"all-slides"`, when a new slide becomes active (including first slide on page load), the first form field will be auto-focused. |
| `buttonAlignment` | `"center"` \| `"end"` \| `"stretch"` | Sets the alignment of the CTA buttons on each slide. |
| `cssPrefix` | `string` | Prefix added to all CSS classes. Default is `"fmd-"`. If set to `"none"`, the prefix is removed altogether. |
| `dir` | `"ltr"` \| `"rtl"` | Direction of the form's text. Default is `"ltr"`. |
| `fieldSize` | `"sm"` | If set to `"sm"`, the size of form fields will be made smaller. |
| `fontSize` | `"sm"` \| `"lg"` | Makes the font size of everything on the form smaller or larger. |
| `formDelimiter` | `string` | Used to separate parameters when creating form fields. Default is `"\|"`. |
| `formsmdBranding` | `"hide"` \| `"show"` | Controls visibility of the Forms.md branding. **Please note**, you need a [Pro subscription](https://forms.md/pricing/) (or above) to hide the branding. |
| `formStyle` | `"classic"` | If set to `"classic"`, the form fields will have a classic appearance. |
| `footer` | `"hide"` \| `"show"` | Controls visibility of the footer. **Please note**, you need a [Pro subscription](https://forms.md/pricing/) (or above) to hide the footer. |
| `header` | `"hide"` \| `"show"` \| `"align"` | Controls header visibility and alignment. |
| `headings` | `"anchored"` | If set to `"anchored"`, all headings will contain an anchor link. |
| `id` | `string` | Identifier for the form. It is highly recommended that every form is given a unique `id`. |
| `labelStyle` | `"classic"` | If set to `"classic"`, the question and description of form fields will be made smaller. |
| `localization` | `string` | Sets the language for automatic translation. Default is `"en"`. |
| `page` | `"form-slides"` \| `"slides"` \| `"single"` | Determines the layout of the form. Default is `"form-slides"`. |
| `pageProgress` | `"hide"` \| `"show"` \| `"decorative"` | Controls visibility and function of the page progress. |
| `placeholders` | `"hide"` \| `"show"` | Controls visibility of input placeholders. |
| `postSheetName` | `string` | When sending responses directly to Google Sheets, specifies which sheet to save responses to. |
| `postUrl` | `string` | URL to send form responses to using POST request. |
| `restartButton` | `"show"` | If set to `"show"`, a restart button will be visible on the end slide. |
| `rounded` | `"none"` \| `"pill"` | Controls rounding of buttons and UI elements. |
| `slideControls` | `"hide"` \| `"show"` | Controls visibility of next and previous buttons. |
| `slideDelimiter` | `string` | Specifies where new slides are created. Default is `"---"`. |
| `submitButtonText` | `string` | Custom text for all submit buttons. |
| `verticalAlignment` | `"start"` | If set to `"start"`, content is aligned to the top of the container vertically. |
| {% endtab %} | | |
{% tab title="Markdown-like" %}
{% hint style="warning" %}
The `formsmd-branding` and/or `footer` parameters can only be set to `hide` if your site has a [Pro subscription](https://forms.md/pricing/) (or above).
{% endhint %}
A setting is a line in the format `#! {name} = {value}` added anywhere (but usually at the very start). For example, `#! button-alignment = center`. The following settings are available:
| Name | Value | Description |
| -------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `autofocus` | `all-slides` | If set to `all-slides`, when a new slide becomes active (including first slide on page load), the first form field will be auto-focused. |
| `button-alignment` | `center` \| `end` \| `stretch` | Sets the alignment of the CTA buttons on each slide. |
| `css-prefix` | `string` | Prefix added to all CSS classes. Default is `fmd-`. If set to `none`, the prefix is removed altogether. |
| `dir` | `ltr` \| `rtl` | Direction of the form's text. Default is `ltr`. |
| `field-size` | `sm` | If set to `sm`, the size of form fields will be made smaller. |
| `font-size` | `sm` \| `lg` | Makes the font size of everything on the form smaller or larger. |
| `form-delimiter` | `string` | Used to separate parameters when creating form fields. Default is `\|`. |
| `formsmd-branding` | `hide` \| `show` | Controls visibility of the Forms.md branding. **Please note**, you need a [Pro subscription](https://forms.md/pricing/) (or above) to hide the branding. |
| `form-style` | `classic` | If set to `classic`, the form fields will have a classic appearance. |
| `footer` | `hide` \| `show` | Controls visibility of the footer. **Please note**, you need a [Pro subscription](https://forms.md/pricing/) (or above) to hide the footer. |
| `header` | `hide` \| `show` \| `align` | Controls header visibility and alignment. |
| `headings` | `anchored` | If set to `anchored`, all headings will contain an anchor link. |
| `id` | `string` | Identifier for the form. It is highly recommended that every form is given a unique `id`. |
| `label-style` | `classic` | If set to `classic`, the question and description of form fields will be made smaller. |
| `localization` | `string` | Sets the language for automatic translation. Default is `"en"`. |
| `page` | `form-slides` \| `slides` \| `single` | Determines the layout of the form. Default is `form-slides`. |
| `page-progress` | `hide` \| `show` \| `decorative` | Controls visibility and function of the page progress. |
| `placeholders` | `hide` \| `show` | Controls visibility of input placeholders. |
| `post-sheet-name` | `string` | When sending responses directly to Google Sheets, specifies which sheet to save responses to. |
| `post-url` | `string` | URL to send form responses to using POST request. |
| `restart-button` | `show` | If set to `show`, a restart button will be visible on the end slide. |
| `rounded` | `none` \| `pill` | Controls rounding of buttons and UI elements. |
| `slide-controls` | `hide` \| `show` | Controls visibility of next and previous buttons. |
| `slide-delimiter` | `string` | Specifies where new slides are created. Default is `---`. |
| `submit-button-text` | `string` | Custom text for all submit buttons. |
| `vertical-alignment` | `start` | If set to `start`, content is aligned to the top of the container vertically. |
| {% endtab %} | | |
| {% endtabs %} | | |
{% hint style="info" %}
More settings are available, but they are mainly relevant for full page forms. See the actual code and test cases to learn more.
{% endhint %}
***
## Options
The `Formsmd` constructor accepts the template of the form, the container where the form will be rendered, and the options to configure form behavior and appearance.
```typescript
constructor(template: string, container: HTMLElement, options: object)
```
### Example
```javascript
const formsmd = new Formsmd(
composer.template,
document.getElementById("my-form-container"),
{
postHeaders: {
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
themeLight: {
accent: "#353148",
accentForeground: "#e2d2b6",
backgroundColor: "#e2d2b6",
color: "#353148"
}
}
);
formsmd.init();
```
### Arguments
| Name | Type | Description |
| ----------- | ------------- | --------------------------------------------------------------- |
| `template` | `string` | The form template string. |
| `container` | `HTMLElement` | The container element where the form will be rendered. |
| `options` | `object` | Object containing configuration options for form functionality. |
### Options parameters
{% hint style="warning" %}
The `formsmdBranding` and/or `footer` parameters can only be set to `"hide"` if your site has a [Pro subscription](https://forms.md/pricing/) (or above).
{% endhint %}
The `options` argument can contain the following parameters:
| Name | Type | Description |
| -------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `colorScheme` | `"light"` \| `"dark"` | Default or initial color scheme of the form. Default is `"light"`. |
| `errorFieldKey` | `string` | Key used to identify the field in error objects. Default is `"field"`. |
| `errorMessageKey` | `string` | Key used to identify the error message in error objects. Default is `"message"`. |
| `footer` | `"hide"` \| `"show"` | Controls visibility of the footer. **Please note**, you need a [Pro subscription](https://forms.md/pricing/) (or above) to hide the footer. |
| `formsmdBranding` | `"hide"` \| `"show"` | Controls visibility of the Forms.md branding. **Please note**, you need a [Pro subscription](https://forms.md/pricing/) (or above) to hide the branding. |
| `getHeaders` | `object` | Headers for GET requests. |
| `isFullPage` | `boolean` | Whether to render in full page mode. Default is `false`. |
| `paddingInlineBottom` | `number` | Padding bottom for inline forms. Default is `20`. |
| `paddingInlineHorizontal` | `number` | Horizontal padding for inline forms. Default is `0`. |
| `paddingInlineTop` | `number` | Padding top for inline forms. Default is `20`. |
| `pageProgress` | `"hide"` \| `"show"` \| `"decorative"` | Controls visibility and function of the page progress. |
| `postData` | `object` | Extra data sent with POST requests. |
| `postHeaders` | `object` | Headers for POST requests. |
| `prioritizeURLFormData` | `boolean` | Whether to prioritize URL form data. Default is `false`. |
| `recaptcha` | `object` | Option for setting up Google reCAPTCHA for spam protection. [Learn more](https://docs.forms.md/getting-started/spam-protection). |
| `sanitize` | `boolean` | Whether to sanitize template. Default is `true`. |
| `saveState` | `boolean` | Whether to save form data in local storage. Default is `true`. |
| `sendFilesAsBase64` | `boolean` | Whether to send files as base64. Default is `false`. |
| `setColorSchemeAttrsAgain` | `boolean` | Whether to set color scheme attributes again. |
| `slideControls` | `"hide"` \| `"show"` | Controls visibility of next and previous buttons. |
| `startSlide` | `number` | The index of the first slide to make active. Default is `0`. |
| `themeDark` | `object` | Dark theme colors. [Learn more](https://docs.forms.md/customization/theming). |
| `themeLight` | `object` | Light theme colors. [Learn more](https://docs.forms.md/customization/theming). |
***
## Difference between form settings and options
There is quite a bit of overlap between form settings and options. Generally speaking, form settings are configuration that is unique to that specific form. Options on the other hand, are meant to be shared among multiple or all forms on your website or app. However, this is a soft rule, and it should always come down to convenience and ease of use.
## FAQs
### [How do I run a function after form submission?](https://docs.forms.md/frequently-asked-questions#how-do-i-run-a-function-after-form-submission)
### [How do get my server's submission errors to work?](https://docs.forms.md/frequently-asked-questions#how-do-get-my-servers-submission-errors-to-work)