LogoLogo
WebsitePricingGitHubSign up
  • Getting started
    • Installation and usage
    • Form settings
    • Options
    • Frequently asked questions
    • Spam protection
    • React
  • Customization
    • Theming
    • Localization
  • Input types
    • Text input
    • Email input
    • URL input
    • Telephone input
    • Password input
    • Number input
    • Select box
    • Choice input
    • Picture choice
    • Rating input
    • Opinion scale / Net Promoter ScoreĀ®
    • Datetime input
    • Date input
    • Time input
    • File input
  • Content
    • Slide
    • Start slide
    • End slide
    • Markdown
    • Data binding
    • CSS utility classes
  • Integrations
    • Google Sheets integration
Powered by GitBook

Ā© 2025 Forms.md | All rights reserved

On this page
  • Use with React
  • Next.js, Remix, Astro, etc., and SSR

Was this helpful?

  1. Getting started

React

Build powerful multi-step forms and surveys in your React app.

Forms.md is a pure JavaScript library with minimal dependencies. All it requires is an input (form template) as a plain string, and a container to render the form in. This means that it is very easy to use with React, Angular, Vue, Svelte, etc. The only "catch" is that the forms only work on the client side, that is, where window and document are available.


Use with React

React is declarative, while the Composer is imperative. This may be slightly off-putting at first. For an easy fix, you may choose to create the form template in another file and just export the template (maybe even keep all the form template files in a separate directory).

Given below is an example of a form working inside a React app:

MailingListForm.tsx

In the component below, the form template is created using the Composer. The actual component only returns an empty <div> element. Once the component has mounted, the form is then initialized and rendered.

// "use client";

import "formsmd/dist/css/formsmd.min.css";
import { useEffect, useRef } from "react";
import { Composer, Formsmd } from "formsmd";

const composer = new Composer({
  id: "mailing-list-form",
  postUrl: "/api/mailing-list",
});

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,
});

export default function MailingListForm() {
  const containerRef = useRef(null);

  useEffect(() => {
    if (containerRef.current) {
      const formsmd = new Formsmd(composer.template, containerRef.current, {
        postHeaders: {
          Authorization: `Basic ${process.env.PUBLIC_API_KEY}`,
        },
      });
      formsmd.init();
    }
  }, []);

  return (
    <div ref={containerRef} style={{ width: "500px", height: "500px" }}></div>
  );
}
// "use client";

import "formsmd/dist/css/formsmd.min.css";
import { useEffect, useRef } from "react";
import { Formsmd } from "formsmd";

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.
)
`;

export default function MailingListForm() {
  const containerRef = useRef(null);

  useEffect(() => {
    if (containerRef.current) {
      const formsmd = new Formsmd(template, containerRef.current, {
        postHeaders: {
          Authorization: `Basic ${process.env.PUBLIC_API_KEY}`,
        },
      });
      formsmd.init();
    }
  }, []);

  return (
    <div ref={containerRef} style={{ width: "500px", height: "500px" }}></div>
  );
}

page.tsx

import MailingListForm from "./MailingListForm";

export default function Home() {
  return (
    <MailingListForm />
  );
}

Next.js, Remix, Astro, etc., and SSR

PreviousSpam protectionNextTheming

Last updated 4 months ago

Was this helpful?

As mentioned above, the forms only work on the client-side. If you're using a framework which uses SSR, you'll need to make sure the components that use Forms.md are rendered only on the client-side. How you do this will vary from framework to framework. For example, in Next.js, this can be done with the directive.

"use client"