Show HN: Open-Source Typeform Alternative

1 month ago 6

Forms.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.

#! 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. )
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();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // 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();
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();
Expand code Collapse code
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();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // 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();
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();

Unlimited form responses

Collect as many responses as you want without any arbitary limits.

Multi-step forms

Create slides with progress indicators to show current step.

Logic jumps

Show or skip slides depending on what the user inputs.

Partial submissions

Slide-level (or partial) submissions to store data on every step.

Collect data of all types

Picture choice, rating, NPS®, date-time, file, etc., plus all basic types.

Data-binding

Display input values that automatically update when the value changes.

Fully customizable

Set the colors, font, and everything else to match your brand.

Localizable

Set localization and automatically translate your forms.

Google Sheets integration

Send your form responses directly to Google Sheets.

Spam protection

Use reCAPTCHA to protect against spam using the built-in integration.

Works with your tech stack

Works with projects written in JavaScript, TypeScript, React, Angular, Vue, Python, Django, etc.

Privacy-focused

No telemetry, the forms are created entirely on the client-side without any iframes. GDPR compliant by default.

Use case

Survey your customers

Collect meaningful feedback through ratings, opinion scales, and Net Promoter Scores®. Create simple, powerful forms that integrate seamlessly into your website or app—giving you the insights you need to grow.

#! id = customer-survey-form #! post-url = /api/customer-survey nps* = OpinionScale( | question = How likely are you to recommend our product to a friend or colleague? ) --- -> nps >= 6 |> 50% email = EmailInput( | question = Would you like to receive product updates? | description = If yes, please enter your email address. We only send high-quality updates and newsletters. )
import { Composer, Formsmd } from "formsmd"; // Create form with ID and submission endpoint const composer = new Composer({ id: "customer-survey-form", postUrl: "/api/customer-survey", }); // Net Promoter Score® composer.opinionScale("nps", { question: "How likely are you to recommend our product to a friend or colleague?", required: true, }); // Start new slide, show only if NPS score is positive, progress indicator at 50% composer.slide({ jumpCondition: "nps >= 6", pageProgress: "50%", }); // Email input for product updates composer.emailInput("email", { question: "Would you like to receive product updates?", description: "If yes, please enter your email address. We only send high-quality updates and newsletters.", }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("customer-survey-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID and submission endpoint const composer = new Composer({ id: "customer-survey-form", postUrl: "/api/customer-survey", }); // Net Promoter Score® composer.opinionScale("nps", { question: "How likely are you to recommend our product to a friend or colleague?", required: true, }); // Start new slide, show only if NPS score is positive, progress indicator at 50% composer.slide({ jumpCondition: "nps >= 6", pageProgress: "50%", }); // Email input for product updates composer.emailInput("email", { question: "Would you like to receive product updates?", description: "If yes, please enter your email address. We only send high-quality updates and newsletters.", }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("customer-survey-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = customer-survey-form #! post-url = /api/customer-survey nps* = OpinionScale( | question = How likely are you to recommend our product to a friend or colleague? ) --- -> nps >= 6 |> 50% email = EmailInput( | question = Would you like to receive product updates? | description = If yes, please enter your email address. We only send high-quality updates and newsletters. ) `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("customer-survey-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
Expand code Collapse code
import { Composer, Formsmd } from "formsmd"; // Create form with ID and submission endpoint const composer = new Composer({ id: "customer-survey-form", postUrl: "/api/customer-survey", }); // Net Promoter Score® composer.opinionScale("nps", { question: "How likely are you to recommend our product to a friend or colleague?", required: true, }); // Start new slide, show only if NPS score is positive, progress indicator at 50% composer.slide({ jumpCondition: "nps >= 6", pageProgress: "50%", }); // Email input for product updates composer.emailInput("email", { question: "Would you like to receive product updates?", description: "If yes, please enter your email address. We only send high-quality updates and newsletters.", }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("customer-survey-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID and submission endpoint const composer = new Composer({ id: "customer-survey-form", postUrl: "/api/customer-survey", }); // Net Promoter Score® composer.opinionScale("nps", { question: "How likely are you to recommend our product to a friend or colleague?", required: true, }); // Start new slide, show only if NPS score is positive, progress indicator at 50% composer.slide({ jumpCondition: "nps >= 6", pageProgress: "50%", }); // Email input for product updates composer.emailInput("email", { question: "Would you like to receive product updates?", description: "If yes, please enter your email address. We only send high-quality updates and newsletters.", }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("customer-survey-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = customer-survey-form #! post-url = /api/customer-survey nps* = OpinionScale( | question = How likely are you to recommend our product to a friend or colleague? ) --- -> nps >= 6 |> 50% email = EmailInput( | question = Would you like to receive product updates? | description = If yes, please enter your email address. We only send high-quality updates and newsletters. ) `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("customer-survey-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();

Use case

Collect employee feedback

Uncover what motivates your employees through engaging surveys that capture authentic feedback on workplace experiences, job satisfaction, and innovative ideas. Transform insights into action.

#! id = employee-feedback-form #! post-url = /api/employee-feedback rating* = RatingInput( | question = How satisfied are you with your current role? ) --- |> 50% feedback = TextInput( | question = Do you have any feedback to help us improve? | description = Share your thoughts on how we can make our company a better place for everyone. | multiline )
import { Composer, Formsmd } from "formsmd"; // Create form with ID and submission endpoint const composer = new Composer({ id: "employee-feedback-form", postUrl: "/api/employee-feedback", }); // Rating input for satisfaction composer.ratingInput("rating", { question: "How satisfied are you with your current role?", required: true, }); // Start new slide, progress indicator at 50% composer.slide({ pageProgress: "50%", }); // Multiline text input for feedback composer.textInput("feedback", { question: "Do you have any feedback to help us improve?", description: "Share your thoughts on how we can make our company a better place for everyone.", multiline: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("employee-feedback-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID and submission endpoint const composer = new Composer({ id: "employee-feedback-form", postUrl: "/api/employee-feedback", }); // Rating input for satisfaction composer.ratingInput("rating", { question: "How satisfied are you with your current role?", required: true, }); // Start new slide, progress indicator at 50% composer.slide({ pageProgress: "50%", }); // Multiline text input for feedback composer.textInput("feedback", { question: "Do you have any feedback to help us improve?", description: "Share your thoughts on how we can make our company a better place for everyone.", multiline: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("employee-feedback-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = employee-feedback-form #! post-url = /api/employee-feedback rating* = RatingInput( | question = How satisfied are you with your current role? ) --- |> 50% feedback = TextInput( | question = Do you have any feedback to help us improve? | description = Share your thoughts on how we can make our company a better place for everyone. | multiline ) `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("employee-feedback-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
Expand code Collapse code
import { Composer, Formsmd } from "formsmd"; // Create form with ID and submission endpoint const composer = new Composer({ id: "employee-feedback-form", postUrl: "/api/employee-feedback", }); // Rating input for satisfaction composer.ratingInput("rating", { question: "How satisfied are you with your current role?", required: true, }); // Start new slide, progress indicator at 50% composer.slide({ pageProgress: "50%", }); // Multiline text input for feedback composer.textInput("feedback", { question: "Do you have any feedback to help us improve?", description: "Share your thoughts on how we can make our company a better place for everyone.", multiline: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("employee-feedback-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID and submission endpoint const composer = new Composer({ id: "employee-feedback-form", postUrl: "/api/employee-feedback", }); // Rating input for satisfaction composer.ratingInput("rating", { question: "How satisfied are you with your current role?", required: true, }); // Start new slide, progress indicator at 50% composer.slide({ pageProgress: "50%", }); // Multiline text input for feedback composer.textInput("feedback", { question: "Do you have any feedback to help us improve?", description: "Share your thoughts on how we can make our company a better place for everyone.", multiline: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("employee-feedback-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = employee-feedback-form #! post-url = /api/employee-feedback rating* = RatingInput( | question = How satisfied are you with your current role? ) --- |> 50% feedback = TextInput( | question = Do you have any feedback to help us improve? | description = Share your thoughts on how we can make our company a better place for everyone. | multiline ) `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("employee-feedback-form-container"), { postHeaders: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, }, ); formsmd.init();

Use case

Mailing list sign up

Grow your subscriber count with beautifully designed forms that turn visitors into loyal followers. Create delightful email capture forms that consistently drive high conversion rates.

#! id = mailing-list-form #! post-url = /api/mailing-list email* = EmailInput( | question = Join our mailing list | description = Stay informed of every update that matters - we'll deliver the latest news straight to your inbox. ) --- -> end # [.text-center] Thank you [.text-center style="font-size: 18px;"] Subscribed to mailing list with {$ email $}.
import { Composer, Formsmd } from "formsmd"; // Create form with ID and submission endpoint const composer = new Composer({ id: "mailing-list-form", postUrl: "/api/mailing-list", }); // Email input composer.emailInput("email", { question: "Join our mailing list", description: "Stay informed of every update that matters - we'll deliver the latest news straight to your inbox.", required: true, }); // End slide with custom message and data-binding composer.endSlide(); composer.h1("Thank you", { classNames: ["text-center"], }); composer.p("Subscribed to mailing list with {$ email $}.", { classNames: ["text-center"], attrs: [ { name: "style", value: "font-size: 18px;", }, ], }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("mailing-list-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID and submission endpoint const composer = new Composer({ id: "mailing-list-form", postUrl: "/api/mailing-list", }); // Email input composer.emailInput("email", { question: "Join our mailing list", description: "Stay informed of every update that matters - we'll deliver the latest news straight to your inbox.", required: true, }); // End slide with custom message and data-binding composer.endSlide(); composer.h1("Thank you", { classNames: ["text-center"], }); composer.p("Subscribed to mailing list with {$ email $}.", { classNames: ["text-center"], attrs: [ { name: "style", value: "font-size: 18px;", }, ], }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("mailing-list-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = mailing-list-form #! post-url = /api/mailing-list email* = EmailInput( | question = Join our mailing list | description = Stay informed of every update that matters - we'll deliver the latest news straight to your inbox. ) --- -> end # [.text-center] Thank you [.text-center style="font-size: 18px;"] Subscribed to mailing list with {$ email $}. `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("mailing-list-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
Expand code Collapse code
import { Composer, Formsmd } from "formsmd"; // Create form with ID and submission endpoint const composer = new Composer({ id: "mailing-list-form", postUrl: "/api/mailing-list", }); // Email input composer.emailInput("email", { question: "Join our mailing list", description: "Stay informed of every update that matters - we'll deliver the latest news straight to your inbox.", required: true, }); // End slide with custom message and data-binding composer.endSlide(); composer.h1("Thank you", { classNames: ["text-center"], }); composer.p("Subscribed to mailing list with {$ email $}.", { classNames: ["text-center"], attrs: [ { name: "style", value: "font-size: 18px;", }, ], }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("mailing-list-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID and submission endpoint const composer = new Composer({ id: "mailing-list-form", postUrl: "/api/mailing-list", }); // Email input composer.emailInput("email", { question: "Join our mailing list", description: "Stay informed of every update that matters - we'll deliver the latest news straight to your inbox.", required: true, }); // End slide with custom message and data-binding composer.endSlide(); composer.h1("Thank you", { classNames: ["text-center"], }); composer.p("Subscribed to mailing list with {$ email $}.", { classNames: ["text-center"], attrs: [ { name: "style", value: "font-size: 18px;", }, ], }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("mailing-list-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = mailing-list-form #! post-url = /api/mailing-list email* = EmailInput( | question = Join our mailing list | description = Stay informed of every update that matters - we'll deliver the latest news straight to your inbox. ) --- -> end # [.text-center] Thank you [.text-center style="font-size: 18px;"] Subscribed to mailing list with {$ email $}. `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("mailing-list-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();

Use case

Simple job posts in minutes

Create simple job posts directly on your website or app. No need to pay for expensive recruiting platforms until you actually need them.

#! form-style = classic #! id = job-post-form #! page-progress = hide #! placeholders = hide #! post-url = /api/apply #! submit-button-text = Apply [.col-6] fullName* = TextInput( | question = Full name ) [.col-6] email* = EmailInput( | question = Email ) cv* = FileInput( | question = CV )
import { Composer, Formsmd } from "formsmd"; // Create form with ID, form styles, and submission endpoint const composer = new Composer({ formStyle: "classic", id: "job-post-form", pageProgress: "hide", placeholders: "hide", postUrl: "/api/apply", submitButtonText: "Apply", }); // Text input for full name composer.textInput("fullName", { question: "Full name", required: true, classNames: ["col-6"], }); // Email input for email address composer.emailInput("email", { question: "Email", required: true, classNames: ["col-6"], }); // File input for CV composer.fileInput("cv", { question: "CV", required: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("job-post-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID, form styles, and submission endpoint const composer = new Composer({ formStyle: "classic", id: "job-post-form", pageProgress: "hide", placeholders: "hide", postUrl: "/api/apply", submitButtonText: "Apply", }); // Text input for full name composer.textInput("fullName", { question: "Full name", required: true, classNames: ["col-6"], }); // Email input for email address composer.emailInput("email", { question: "Email", required: true, classNames: ["col-6"], }); // File input for CV composer.fileInput("cv", { question: "CV", required: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("job-post-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! form-style = classic #! id = job-post-form #! page-progress = hide #! placeholders = hide #! post-url = /api/apply #! submit-button-text = Apply [.col-6] fullName* = TextInput( | question = Full name ) [.col-6] email* = EmailInput( | question = Email ) cv* = FileInput( | question = CV ) `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("job-post-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
Expand code Collapse code
import { Composer, Formsmd } from "formsmd"; // Create form with ID, form styles, and submission endpoint const composer = new Composer({ formStyle: "classic", id: "job-post-form", pageProgress: "hide", placeholders: "hide", postUrl: "/api/apply", submitButtonText: "Apply", }); // Text input for full name composer.textInput("fullName", { question: "Full name", required: true, classNames: ["col-6"], }); // Email input for email address composer.emailInput("email", { question: "Email", required: true, classNames: ["col-6"], }); // File input for CV composer.fileInput("cv", { question: "CV", required: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("job-post-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID, form styles, and submission endpoint const composer = new Composer({ formStyle: "classic", id: "job-post-form", pageProgress: "hide", placeholders: "hide", postUrl: "/api/apply", submitButtonText: "Apply", }); // Text input for full name composer.textInput("fullName", { question: "Full name", required: true, classNames: ["col-6"], }); // Email input for email address composer.emailInput("email", { question: "Email", required: true, classNames: ["col-6"], }); // File input for CV composer.fileInput("cv", { question: "CV", required: true, }); // Initialize with template, container, and options const formsmd = new Formsmd( composer.template, document.getElementById("job-post-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! form-style = classic #! id = job-post-form #! page-progress = hide #! placeholders = hide #! post-url = /api/apply #! submit-button-text = Apply [.col-6] fullName* = TextInput( | question = Full name ) [.col-6] email* = EmailInput( | question = Email ) cv* = FileInput( | question = CV ) `; // Initialize with template, container, and options const formsmd = new Formsmd( template, document.getElementById("job-post-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, }, ); formsmd.init();

Feature

Translate, customize, and make it entirely yours

Change the localization setting to automatically translate your forms. Easily set the colors, font, and everything else to match your brand, seamlessly blending in the forms on your website or app. There's also a handy translate({...}) function that lets you define your translations directly in the form composer for dynamic localization.

#! id = ja-customer-survey-form #! localization = ja #! post-url = /api/customer-survey #! rounded = none nps* = OpinionScale( | question = 当社の製品を友人や同僚に推薦する可能性はどの程度ありますか? )
import { Composer, Formsmd } from "formsmd"; // Create form with ID, localization, submission endpoint, and border radius const composer = new Composer({ id: "ja-customer-survey-form", localization: "ja", postUrl: "/api/customer-survey", rounded: "none", }); // Net Promoter Score® composer.opinionScale("nps", { question: "当社の製品を友人や同僚に推薦する可能性はどの程度ありますか?", required: true, }); // Initialize with template, container, and options with theming const formsmd = new Formsmd( composer.template, document.getElementById("ja-customer-survey-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, themeDark: { accent: "#dfdfdf", }, themeLight: { accent: "rgb(26, 26, 26)", }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID, localization, submission endpoint, and border radius const composer = new Composer({ id: "ja-customer-survey-form", localization: "ja", postUrl: "/api/customer-survey", rounded: "none", }); // Net Promoter Score® composer.opinionScale("nps", { question: "当社の製品を友人や同僚に推薦する可能性はどの程度ありますか?", required: true, }); // Initialize with template, container, and options with theming const formsmd = new Formsmd( composer.template, document.getElementById("ja-customer-survey-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, themeDark: { accent: "#dfdfdf", }, themeLight: { accent: "rgb(26, 26, 26)", }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = ja-customer-survey-form #! localization = ja #! post-url = /api/customer-survey #! rounded = none nps* = OpinionScale( | question = 当社の製品を友人や同僚に推薦する可能性はどの程度ありますか? ) `; // Initialize with template, container, and options with theming const formsmd = new Formsmd( template, document.getElementById("ja-customer-survey-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, themeDark: { accent: "#dfdfdf", }, themeLight: { accent: "rgb(26, 26, 26)", }, }, ); formsmd.init();
Expand code Collapse code
import { Composer, Formsmd } from "formsmd"; // Create form with ID, localization, submission endpoint, and border radius const composer = new Composer({ id: "ja-customer-survey-form", localization: "ja", postUrl: "/api/customer-survey", rounded: "none", }); // Net Promoter Score® composer.opinionScale("nps", { question: "当社の製品を友人や同僚に推薦する可能性はどの程度ありますか?", required: true, }); // Initialize with template, container, and options with theming const formsmd = new Formsmd( composer.template, document.getElementById("ja-customer-survey-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, themeDark: { accent: "#dfdfdf", }, themeLight: { accent: "rgb(26, 26, 26)", }, }, ); formsmd.init();
import { Composer } from "formsmd"; import { FormsmdComponent } from "formsmd-react"; // Create form with ID, localization, submission endpoint, and border radius const composer = new Composer({ id: "ja-customer-survey-form", localization: "ja", postUrl: "/api/customer-survey", rounded: "none", }); // Net Promoter Score® composer.opinionScale("nps", { question: "当社の製品を友人や同僚に推薦する可能性はどの程度ありますか?", required: true, }); // Initialize with template, container, and options with theming const formsmd = new Formsmd( composer.template, document.getElementById("ja-customer-survey-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, themeDark: { accent: "#dfdfdf", }, themeLight: { accent: "rgb(26, 26, 26)", }, }, ); formsmd.init();
import { Formsmd } from "formsmd"; // Create template const template = ` #! id = ja-customer-survey-form #! localization = ja #! post-url = /api/customer-survey #! rounded = none nps* = OpinionScale( | question = 当社の製品を友人や同僚に推薦する可能性はどの程度ありますか? ) `; // Initialize with template, container, and options with theming const formsmd = new Formsmd( template, document.getElementById("ja-customer-survey-form-container"), { postHeaders: { Authorization: "Basic <API_KEY>", }, themeDark: { accent: "#dfdfdf", }, themeLight: { accent: "rgb(26, 26, 26)", }, }, ); formsmd.init();

Feature

Save form submissions directly in Google Sheets

Use our Apps Script integration to save form submissions directly in your Google Sheets. It also supports spam protection with Google reCAPTCHA and file uploads via Google Drive. Please watch the video to get started, or read the docs to learn more.

Pricing

Get everything, forever

All features on Forms.md are completely free without any arbitary usage limits. You only need to pay to remove the branding on the forms. Our product delivers enterprise-level functionality with a lifetime access deal. No subscriptions, free updates, just pay once and use forever. Read the honest pitch about how and why.

  • Yes: 1 end product
  • Yes: All features available
  • Yes: Use for personal or client
  • Yes: Unlimited form responses
  • Yes: Lifetime access & updates for v1
  • No: Email/chat support
  • No: Remove Forms.md branding

Pro single-site

Remove branding

$99/one time payment

Tax inclusive

  • Yes: 1 end product
  • Yes: All features available
  • Yes: Use for personal or client
  • Yes: Unlimited form responses
  • Yes: Lifetime access & updates for v1
  • Yes: Email/chat support
  • Yes: Remove Forms.md branding

Pro multi-site

Remove branding

$299/one time payment

Tax inclusive

  • Yes: Unlimited end products
  • Yes: All features available
  • Yes: Use for personal or client
  • Yes: Unlimited form responses
  • Yes: Lifetime access & updates for v1
  • Yes: Email/chat support
  • Yes: Remove Forms.md branding
Read Entire Article