# React

**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

{% hint style="warning" %}
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).
{% endhint %}

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.

{% tabs %}
{% tab title="With composer" %}

```tsx
// "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>
  );
}
```

{% endtab %}

{% tab title="Markdown-like" %}

```tsx
// "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>
  );
}
```

{% endtab %}
{% endtabs %}

#### page.tsx

```jsx
import MailingListForm from "./MailingListForm";

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

***

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

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 [`"use client"`](https://nextjs.org/docs/app/building-your-application/rendering/client-components) directive.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forms.md/getting-started/react.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
