Merge branch 'main' of github.com:formbricks/formbricks

This commit is contained in:
Matthias Nannt
2023-02-10 15:29:43 +01:00
121 changed files with 1591 additions and 2655 deletions

View File

@@ -0,0 +1,82 @@
import clsx from "clsx";
import { usePlausible } from "next-plausible";
import Script from "next/script";
import { useEffect, useRef, useState } from "react";
declare global {
interface Window {
formbricks: any;
}
}
export default function FeedbackButton() {
const plausible = usePlausible();
const [isOpen, setIsOpen] = useState(false);
const feedbackRef = useRef<HTMLInputElement>(null);
useEffect(() => {
// Close the feedback form if the user clicks outside of it
function handleClickOutside(event: any) {
if (feedbackRef.current && !feedbackRef.current.contains(event.target)) {
if (isOpen) setIsOpen(false);
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [feedbackRef, isOpen]);
return (
<>
<Script src="https://cdn.jsdelivr.net/npm/@formbricks/feedback@0.2.1/dist/index.umd.js" defer />
<Script id="feedback-setup">{`
window.formbricks = {
...window.formbricks,
config: {
hqUrl: "https://app.formbricks.com",
formId: "cldipnvz80002le0ha2a3zhgl",
divId: "formbricks-feedback-wrapper",
contact: {
name: "Matti",
position: "Co-Founder",
imgUrl: "https://avatars.githubusercontent.com/u/675065?s=128&v=4",
},
},
};`}</Script>
<div
className={clsx(
"xs:flex-row xs:w-[18rem] xs:-translate-y-1/2 z-50 h-fit w-full transition-all duration-500 ease-in-out",
isOpen ? "xs:-translate-x-0 translate-y-0" : "xs:translate-x-full xs:-mr-1 translate-y-full"
)}>
<div
className="xs:flex-row flex h-full flex-col"
onClick={(e) => {
e.stopPropagation();
}}
ref={feedbackRef}>
<button
className="xs:-rotate-90 xs:top-1/2 xs:-left-[5.75rem] xs:-translate-y-1/2 xs:-translate-x-0 xs:w-32 xs:p-4 bg-brand-dark absolute left-1/2 w-28 -translate-x-1/2 -translate-y-full rounded-t-lg p-3 font-medium text-white"
onClick={() => {
if (!isOpen) {
plausible("openFeedback");
if (window) {
window.formbricks.render();
window.formbricks.resetForm();
}
}
setIsOpen(!isOpen);
}}>
{isOpen ? "Close" : "Feedback"}
</button>
<div
className="xs:rounded-bl-lg xs:rounded-tr-none h-full w-full overflow-hidden rounded-bl-none rounded-tr-lg rounded-tl-lg bg-slate-50 shadow-lg"
id="formbricks-feedback-wrapper"></div>
</div>
</div>
</>
);
}

View File

@@ -0,0 +1,33 @@
import { Button } from "@formbricks/ui";
import { useEffect, useRef, useState } from "react";
declare global {
interface Window {
formbricks: any;
}
}
export function FeedbackButton() {
useEffect(() => {
window.formbricks = {
...window.formbricks,
config: {
hqUrl: process.env.NEXT_PUBLIC_FORMBRICKS_URL,
formId: process.env.NEXT_PUBLIC_FORMBRICKS_FORM_ID,
contact: {
name: "Matti",
position: "Co-Founder",
imgUrl: "https://avatars.githubusercontent.com/u/675065?s=128&v=4",
},
},
};
// @ts-ignore
import("@formbricks/feedback");
}, []);
return (
<Button variant="secondary" onClick={(e) => window.formbricks.open(e)}>
Open Feedback
</Button>
);
}

View File

@@ -2,7 +2,6 @@ import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/router";
import clsx from "clsx";
import { Hero } from "@/components/shared/Hero";
import { FooterLogo, Logomark } from "@/components/shared/Logo";
import { MobileNavigation } from "@/components/shared/MobileNavigation";
@@ -42,7 +41,7 @@ function Header({ navigation }: any) {
className={clsx(
"sticky top-0 z-50 flex flex-wrap items-center justify-between bg-slate-100 px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 dark:shadow-none sm:px-6 lg:px-8",
isScrolled
? "bg-slate-100/90 backdrop-blur dark:bg-slate-900/90 [@supports(backdrop-filter:blur(0))]:bg-slate-100/75 dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75"
? "[@supports(backdrop-filter:blur(0))]:bg-slate-100/75 dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75 bg-slate-100/90 backdrop-blur dark:bg-slate-900/90"
: "dark:bg-transparent"
)}>
<div className="mr-6 flex lg:hidden">
@@ -61,7 +60,7 @@ function Header({ navigation }: any) {
<Button
variant="secondary"
EndIcon={GitHubIcon}
endIconClassName="fill-slate-800 dark:fill-slate-200"
endIconClassName="fill-slate-800 dark:fill-slate-200 ml-2"
onClick={() => router.push("https://github.com/formbricks/formbricks")}>
View on Github
</Button>
@@ -125,6 +124,15 @@ export function Layout({ children, meta }: LayoutProps) {
</header>
)}
<Prose className="">{children}</Prose>
<div className="mt-16 rounded-xl border-2 border-slate-200 bg-slate-300 p-8 dark:border-slate-700/50 dark:bg-slate-800">
<h4 className="text-3xl font-semibold text-slate-500 dark:text-slate-50">Need help?</h4>
<p className="my-4 text-slate-500 dark:text-slate-400">
Join our Discord and ask away. We&apos;re happy to help where we can!
</p>
<Button variant="highlight" href="/discord" target="_blank">
Join Discord
</Button>
</div>
</article>
<dl className="mt-12 flex border-t border-slate-200 pt-6 dark:border-slate-800">
{previousPage && (

View File

@@ -27,7 +27,7 @@ interface APICallProps {
}
export function APILayout({ method, url, description, queries, bodies, responses, example }: APICallProps) {
const [switchState, setSwitchState] = useState(false);
const [switchState, setSwitchState] = useState(true);
function handleOnChange() {
setSwitchState(!switchState);
}
@@ -50,16 +50,16 @@ export function APILayout({ method, url, description, queries, bodies, responses
<div
className={clsx(
"mr-3 inline rounded-full p-1 px-3 font-semibold text-white",
method === "POST" && "bg-red-400",
method === "GET" && "bg-green-400"
method === "POST" && "bg-red-400 dark:bg-red-800",
method === "GET" && "bg-green-400 dark:bg-green-800"
)}>
{method}
</div>
<div className="inline text-sm text-slate-500">
http://localhost:300/api
<span className="font-bold text-black">{url}</span>
<div className="inline text-sm text-slate-500 ">
http://localhost:300
<span className="font-bold text-black dark:text-slate-300">{url}</span>
</div>
<div className="mt-4 ml-8 font-bold">{description}</div>
<div className="mt-4 ml-8 font-bold dark:text-slate-400">{description}</div>
<div>
<div className={clsx(switchState ? "block" : "hidden", "ml-8")}>
<p className="mt-6 mb-2 text-lg font-semibold">Parameters</p>
@@ -88,7 +88,11 @@ export function APILayout({ method, url, description, queries, bodies, responses
{example && (
<div>
<p className="not-prose mb-2 pt-2 font-bold">Body Example</p>
<div className="rounded-lg bg-slate-300 p-2 font-mono text-sm">{example}</div>
<div>
<pre>
<code>{example}</code>
</pre>
</div>
</div>
)}
</div>
@@ -187,7 +191,9 @@ function Response({ color, statusCode, description, example }: RespProps) {
</div>
</div>
{example && toggleExample && (
<div className="col-span-2 my-3 rounded-lg bg-slate-300 p-2 font-mono">{example}</div>
<div className="col-span-2 my-3 rounded-lg bg-slate-300 p-2 font-mono dark:bg-slate-600 dark:text-slate-300">
{example}
</div>
)}
</div>
);

View File

@@ -35,6 +35,11 @@ export default function Header() {
className="text-base font-medium text-slate-400 hover:text-slate-700 dark:hover:text-slate-300">
Pricing <p className="bg-brand inline rounded-full px-2 text-xs text-white">50%</p>
</Link>
<Link
href="/docs"
className="text-base font-medium text-slate-400 hover:text-slate-700 dark:hover:text-slate-300">
Docs
</Link>
</Popover.Group>
<div className="hidden flex-1 items-center justify-end md:flex">
<ThemeSelector className="relative z-10 mr-5" />
@@ -80,6 +85,7 @@ export default function Header() {
<div className="flex flex-col space-y-5 text-center text-sm dark:text-slate-300">
<Link href="#howitworks">How it works</Link>
<Link href="#pricing">Pricing</Link>
<Link href="/docs">Docs</Link>
<Button
variant="secondary"
target="_blank"

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@@ -2,105 +2,87 @@ const navigation = [
{
title: "Introduction",
links: [
{ title: "Why Formbricks?", href: "/docs/introduction/why-formbricks" },
{ title: "How to achieve this?", href: "/docs/introduction/how-to-achieve-this" },
{ title: "What is Formbricks?", href: "/docs/introduction/what-is-formbricks" },
{ title: "Quick start", href: "/docs/introduction/quick-start" },
{ title: "Why is it better?", href: "/docs/introduction/why-is-it-better" },
{ title: "How does it work?", href: "/docs/introduction/how-it-works" },
],
},
{
title: "React Form Library",
title: "Best Practices",
links: [
{
title: "Introduction",
href: "/docs/react-form-library/introduction",
title: "What are Best Practices?",
href: "/docs/best-practices/what-are-best-practices",
},
{
title: "Getting started",
href: "/docs/react-form-library/getting-started",
title: "Feedback Box",
href: "/docs/best-practices/feedback-box",
},
{
title: "Link with Formbricks HQ",
href: "/docs/react-form-library/link-formbricks-hq",
title: "Product-Market Fit Survey",
href: "/docs/best-practices/pmf-survey",
},
{
title: "Work with Components",
href: "/docs/react-form-library/work-with-components",
title: "Onboarding Segmentation",
href: "/docs/best-practices/onboarding-segmentation",
},
{
title: "Validation & Errors",
href: "/docs/react-form-library/validation-errors",
title: "Waitlist Survey",
href: "/docs/best-practices/waitlist-survey",
},
{
title: "Form Wrapper",
href: "/docs/react-form-library/form-wrapper",
},
{
title: "Input: Checkbox",
href: "/docs/react-form-library/input-checkbox",
},
{
title: "Input: Email",
href: "/docs/react-form-library/input-email",
},
{
title: "Input: Number",
href: "/docs/react-form-library/input-number",
},
{
title: "Input: Password",
href: "/docs/react-form-library/input-password",
},
{
title: "Input: Phone",
href: "/docs/react-form-library/input-phone",
},
{
title: "Input: Text",
href: "/docs/react-form-library/input-text",
},
{
title: "Input: Textarea",
href: "/docs/react-form-library/input-textarea",
},
{
title: "Input: Radio Button",
href: "/docs/react-form-library/input-radio",
},
{
title: "Input: URL",
href: "/docs/react-form-library/input-url",
},
{
title: "Input: Search",
href: "/docs/react-form-library/input-search",
},
{
title: "Input: Submit",
href: "/docs/react-form-library/input-submit",
},
{
title: "Style with CSS",
href: "/docs/react-form-library/style-css",
},
{
title: "Style with Tailwind",
href: "/docs/react-form-library/style-tailwind",
},
{
title: "Icons",
href: "/docs/react-form-library/icons",
title: "Interview Prompt",
href: "/docs/best-practices/interview-prompt",
},
],
},
{
title: "Formbricks HQ",
title: "Wrappers",
links: [
{ title: "Core API", href: "/docs/formbricks-hq/core-api" },
{ title: "Schema", href: "/docs/formbricks-hq/schema" },
{ title: "Email Notifications (UI)", href: "/docs/formbricks-hq/ui/email-notifications" },
{ title: "Webhooks (UI)", href: "/docs/formbricks-hq/ui/webhooks" },
{ title: "Self-Hosting", href: "/docs/formbricks-hq/self-hosting" },
{
title: "What are Wrappers?",
href: "/docs/wrappers/what-are-wrappers",
},
{
title: "In-app Pop-over",
href: "/docs/wrappers/pop-over",
},
{
title: "In-app Slide-out",
href: "/docs/wrappers/slide-out",
},
{
title: "Modal",
href: "/docs/wrappers/modal",
},
{
title: "Inline",
href: "/docs/wrappers/inline",
},
{
title: "Link",
href: "/docs/wrappers/link",
},
{
title: "Email",
href: "/docs/wrappers/email",
},
],
},
{
title: "API",
links: [
{ title: "API Setup", href: "/docs/api/setup" },
{ title: "Create Submission", href: "/docs/api/create-submission" },
{ title: "Update Submission", href: "/docs/api/update-submission" },
{ title: "Update Schema", href: "/docs/api/update-schema" },
],
},
{
title: "Self-hosting",
links: [
{ title: "Quick Start", href: "/docs/self-hosting/quick-start" },
{ title: "Deployment", href: "/docs/self-hosting/deployment" },
],
},
];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,95 +0,0 @@
import Image from "next/image";
import LayoutMdx from "@/components/shared/LayoutMdx";
import NewsletterSignup from "@/components/shared/NewsletterSignup";
import LaunchDay from "./launch formbricks HQ open source alternative formspree.png";
import Polling from "../weekly-update-021222/chart-3.webp";
import Schema from "../../docs/formbricks-hq/schema/data-visualisation-open-source-survey-builder.png";
import NoSchema from "../../docs/formbricks-hq/schema/no-schema-visualisation-of-open-source-data-form-builder-creator-webform.png";
import NPS1 from "./NPS-filled-out.webp";
import NPS2 from "./NPS-feedback-summary.webp";
import NPS3 from "./NPS-feedback-overview.webp";
import API from "./API-endpoint.webp";
export const meta = {
title: "Formbricks HQ launched! 🚀",
description:
"we are thrilled to announce the launch of Formbricks HQ, the newest addition to our suite of open source survey tools!",
date: "2022-12-08",
};
<Image src={LaunchDay} alt="Formbricks HQ launched" className="rounded-lg" />
_Today, we are thrilled to announce the launch of Formbricks HQ, the newest addition to our suite of open source survey tools! Formbricks HQ is an easy-to-use product that allows developers to quickly and easily create, manage, and deploy forms for their websites, without the need for a server._
### What can you use it for?
In our last [Weekly Update](/blog/weekly-update-021222), we already shared the use case of polling users natively in your app or webshop and showing them the results right away.
<Image src={Polling} alt="Polling users natively in-app" className="rounded-lg" />
## Use case: Native NPS survey
To showcase the power of Formbricks HQ, we built another common use case: The NPS survey. We used Formbricks React to build the survey natively into our example app. When the survey is submitted, the data is sent to Formbricks HQ and displayed.
### Step 1: Create NPS survey in Formbricks HQ
With a few clicks you create a new form in Formbricks HQ:
<Image src={API} alt="Polling users natively in-app" className="rounded-lg" />
### Step 2: Using Formbricks React to build the survey
We built the NPS survey with Formbricks React. It is a simple form with two questions and a submit button. The form is built with the following code:
```jsx
import { Form, Nps, sendToHq, Submit, Textarea } from "@formbricks/react";
<Form formId="clbfbfqjh0000jz0803qh43y8" customerId="yourcustomer@company.com" onSubmit={sendToHq}>
<Nps name="nps" label="How likely are you to recommend Formbricks to a friend or colleague?" />
<Textarea name="feedback" label="Your feedback" cols={30} />
<Submit label="Submit" />
</Form>;
```
<Image src={NPS1} alt="NPS natively embedded into app" className="rounded-lg" />
From the HQ you can copy the endpoint to your form action. The endpoint is a POST request which accepts JSON data. The data is then sent to your personal endpoint hosted on Formbricks HQ.
### Step 3: Displaying the results
The results are displayed in the HQ dashboard. You can see the results in real-time. The dashboard is built with [Formbricks Charts](https://www.npmjs.com/package/@formbricks/charts) and uses the same schema as [Formbricks React](https://www.npmjs.com/package/@formbricks/react).
<Image src={NPS2} alt="Results summary" className="rounded-lg" />
<Image src={NPS3} alt="Results overview" className="rounded-lg" />
### What is a schema good for?
The cool thing - apart from you being able to self-host and customize the complete solution - is that Frombricks React and HQ are using the same schema.
Weve wrote about the [benefit in-depth in our Docs](/docs/formbricks-hq/schema), but here is the benefit in a nutshell:
You get a full image of the survey data including questions and not selected options. Without a schema, your stuck with the data which is sent along so the selected value and the input label. Here is the difference:
<Image src={NoSchema} alt="Open Source Form with Question about favorite food" className="rounded-lg" />
<Image src={Schema} alt="Open Source Form with Question about favorite food" className="rounded-lg" />
And just like that you have a native NPS survey with full data insights! 🚀
## What else can you use Formbricks HQ for?
Apart from the use case above, you can send any form data to your personal endpoint. Here is a short tutorial on how to do that, [the full guide is in our docs](/docs/react-form-library/link-formbricks-hq):
1. Sign up at [hq.formbricks.com](https://hq.formbricks.com)
2. Create a new form
3. Copy the endpoint to your form action
4. Receive responses
### What do you think?
[Join our Discord to share feedback and request features!](https://formbricks.com/discord)
<NewsletterSignup />
export default ({ children }) => <LayoutMdx meta={meta}>{children}</LayoutMdx>;

View File

@@ -1,71 +0,0 @@
import Image from "next/image";
import LayoutMdx from "@/components/shared/LayoutMdx";
import LaunchDay from "./launch2-react library form builder survey with multi-step form open-source.png";
import MdxTryItCTA from "@/components/shared/MdxTryItCTA.tsx";
import Styling from "../../docs/react-form-library/style-css/HTML classes of Formbricks React Form Library to custom style surveys and forms.png";
import CodeExample from "./v2 developer experience best react library 2023 forms and surveys open source.png";
export const meta = {
title: "React Form Library launched! 🚀 [Updated]",
description: "We are pumped to announce that the Formbricks React Form Library is ready to be used!",
date: "2022-11-24",
};
<Image src={LaunchDay} alt="Robin Hood Meme" className="rounded-lg" />
### Why a React Library?
We have built form and survey solutions for companies in different stages. Even though forms have been around for a long while, we kept finding ourselves writing custom code for basic functionality over and over again. Formbricks React will provide all form functionality out of the box and speed up writing forms and surveys in React significantly.
### How is the developer experience better?
We want to make forms in React more accessible. To achieve that, we work with:
- **Component-based approach:** Import HTML and non-HTML questions types with one line of code
- **Props:** Specify every aspect of each form field like name, label, placeholder and validation with props in each component
- **Styling:** Give your form a native look & feel in minutes. We natively support Tailwind and regular CSS style sheets.
<Image src={CodeExample} alt="Robin Hood Meme" className="rounded-lg" />
### What does it come with? [Updated]
In version 0.1 we layed the foundation for performant, easy to build forms. The library includes:
- Text Input
- Textarea Input
- Checkboxes
- Radio Buttons
- Phone Input
- Email Input
- URL Input
- Password Input
- Search Input
- Submit Button with Icons
And additional features like
- Validation & Error Messages
- Tailwind Support
- Standard CSS Support
<Image src={Styling} alt="Robin Hood Meme" className="rounded-lg" />
### Whats on the roadmap?
- Common non-HTML question types (Slider, star-rating, NPS, toggle, etc.)
- Easy multi-step forms
- Easy form logic
- Easy internationalization (i18n)
- Accessibility out of the box (a11y)
### Suggest a feature
We run open source and community-centered. If youd like a specific feature, [just ask for it in our Discord :)](https://formbricks.com/discord)
### Documentation
Youll find a lot more [information in the Docs.](/docs)
<MdxTryItCTA />
export default ({ children }) => <LayoutMdx meta={meta}>{children}</LayoutMdx>;

View File

@@ -8,8 +8,8 @@ import HQ1 from "./hq-1.webp";
import HQAPI from "./hq-api.webp";
import HQOverview from "./hq-overview.webp";
import HQSummary from "./hq-summary.webp";
import NPS1 from "../launch-formbricks-hq/NPS-filled-out.webp";
import NPS2 from "../launch-formbricks-hq/NPS-feedback-summary.webp";
import NPS1 from "./NPS-filled-out.webp";
import NPS2 from "./NPS-feedback-summary.webp";
export const meta = {
title: "Weekly Summary - 9th Dec 2022",

View File

@@ -3,7 +3,7 @@ import LayoutMdx from "@/components/shared/LayoutMdx";
import NewsletterSignup from "@/components/shared/NewsletterSignup";
import HeaderImage from "../weekly-update-181122/weeklyupdate.png";
import HeroAnimation from "@/components/shared/HeroAnimation";
import PmfDummy from "@/components/shared/PmfDummy";
import PmfDummy from "@/components/docs/PmfDummy";
import PMFDashboard from "./pmf-dashboard.png";
import Waitlist from "./waitlist-cr.png";

View File

@@ -0,0 +1,76 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { APILayout } from "@/components/shared/APILayout.tsx";
export const meta = {
title: "API: Create submission",
};
<APILayout
method="POST"
url="/api/capture/forms/{formId}/submissions"
description="Add a new submission to a form by form ID."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{
label: "customer",
type: "JSON",
description: "The customer and metadata you want to link the submission to.",
},
{
label: "customer.email",
type: "email",
description: "Customer or user email. This is the primary key to identify users",
required: true,
},
{
label: "customer.prop",
type: "string",
description:
"Pass value to create user property. You can filter / create cohorts for future surveys based on props.",
},
{
label: "data",
type: "JSON",
description: "The content of the submission.",
},
{
label: "data.fieldName",
type: "string",
description: "Add value to input field by name.",
required: true,
},
{
label: "finished",
type: "boolean",
description: "Determines if submission is complete.",
},
]}
example={`{
"data": {
"rating": 10,
"message": "I love Formbricks"
},
"customer": {
"email": "hola@formbricks.com", //required
"name": "Johnny"
},
"finished": true
}`}
responses={[
{
color: "green",
statusCode: "200",
description: "success",
example: "{ // Response }",
},
]}
/>
| field name | required | default | description |
| ---------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data | yes | - | The submission object (answers to the form/survey) |
| customer | no | - | The customer this submission is connected to. The customer object must contain an email field. All other fields are optional and get saved as user properties. |
| finished | no | false | Mark a submission as complete to be able to filter accordingly |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,32 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { APILayout } from "@/components/shared/APILayout.tsx";
import { Callout } from "@/components/shared/Callout";
export const meta = {
title: "API Setup",
};
## Auth: Personal API key
The API requests are authorized with a personal API key. This API key gives you the same rights as if you were logged in at formbricks.com - **don't share it around!**
### How to generate an API key
1. Go to your profile at [app.formbricks.com](https://app.formbricks.com/app/me/settings).
2. Select “Add key”.
3. Label it (this is just for you).
4. Copy the key. You wont be able to see it again.
<Callout title="Store API key safely" type="warning">
Anyone who has your API key has full control over your account. For security reasons, you cannot view the
API key again.
</Callout>
### Delete a personal API key
1. Go to your profile at [app.formbricks.com](https://app.formbricks.com/app/me/settings).
2. Find the key you wish to revoke and select “Delete”.
3. Your API key will stop working immediately.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,75 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { APILayout } from "@/components/shared/APILayout.tsx";
export const meta = {
title: "API: Update schema",
};
<APILayout
method="POST"
url="/api/capture/forms/{formId}/submissions/schema"
description="Update the schema of a form in Formbricks."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{
label: "pages",
type: "List of JSON",
description: "Array of all pages of the form.",
},
{
label: "pages[].id",
type: "string",
description: "Unique page ID.",
},
{
label: "pages[].elements",
type: "List of JSON",
description: "Array of all input elements of this page.",
},
{
label: "pages[].elements[].id",
type: "string",
description: "Unique input ID.",
},
{
label: "pages[].elements[].name",
type: "string",
description: "Field name.",
},
{
label: "pages[].elements[].type",
type: "string",
description: "Input type.",
},
{
label: "pages[].elements[].label",
type: "string",
description: "Input label, usually a question.",
},
]}
example={`{
"pages":
[{
"id": "emailPage",
"elements":
[{
"id": "email",
"name": "email",
"type": "text",
"label": "What's your email address?",
}]
}]
}
`}
responses={[
{
color: "green",
statusCode: "200",
description: "success",
example: "{ // Response }",
},
]}
/>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,75 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { APILayout } from "@/components/shared/APILayout.tsx";
export const meta = {
title: "API: Update submission",
};
<APILayout
method="POST"
url="/api/capture/forms/{formId}/submissions/{submissionId}"
description="Update an existing submission in a form by form ID."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{
label: "customer",
type: "JSON",
description: "The customer and metadata you want to link the submission to.",
},
{
label: "customer.email",
type: "email",
description: "Customer or user email. This is the primary key to identify users",
required: true,
},
{
label: "customer.prop",
type: "string",
description:
"Pass value to create user property. You can filter / create cohorts for future surveys based on props.",
},
{
label: "data",
type: "JSON",
description: "The content of the submission.",
},
{
label: "data.fieldName",
type: "string",
description: "Add value to input field by name.",
required: true,
},
{
label: "finished",
type: "boolean",
description: "Determines if submission is complete.",
},
]}
example={`{
"data": {
"country": "Germany",
},
"customer": {
"email": "hola@formbricks.com", // required
"country": "Germany"
},
"finished": true
}`}
responses={[
{
color: "green",
statusCode: "200",
description: "success",
example: "{ // Response }",
},
]}
/>
| field name | required | default | description |
| ---------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data | yes | - | The submission object (answers to the form/survey) |
| customer | no | - | The customer this submission is connected to. The customer object must contain an email field. All other fields are optional and get saved as user properties. |
| finished | no | false | Mark a submission as complete to be able to filter accordingly |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,182 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import Link from "next/link";
export const meta = {
title: "Feedback Box",
};
The Feedback Box is an easy way to gather feedback from users in your app.
## Purpose
Allow users to share feedback with 2 clicks. A low friction way to gather feedback helps catching even the smallest points of annoyance / frustration in user experiences.
## Formbricks Approach
- Make it **easy**: 2 clicks
- Keep it **personal**: Founder faces
- **Pre-sort** feedback:
- Bug → Pipe into Bug channel for devs
- Feedback → Pipe into Feedback channel for PMs
- Appreciation → Pipe into General channel for team spirit & testimonials
## Preview
## Installation
To add the Feedback Box to your app, you need to perform three steps:
1. Install
2. Configure
3. Embed
### 1. Install
There are two ways to install the Feedback Box: npm and JavaScript embed.
**NPM Install**
```tsx
npm install @formbricks/feedback
```
**JavaScript Embed**
You can also embed the Feedback Box in your HTML `<head>` tag:
```tsx
<script src="https://cdn.jsdelivr.net/npm/@formbricks/feedback@0.2" defer></script>
```
### 2. Setting up the config
You can change the content behaviour of the Feedback Box with the config object.
**Basic config**
Add your Formbricks form ID and the formbricks server address to the config object.
```html
<script>
window.formbricks = {
...window.formbricks,
config: {
formbricksUrl: "https://app.formbricks.com",
formId: "cldipnvz80002le0ha2a3zhgl",
},
};
</script>
```
**Personalizing**
Add your name, position and image link to give users the impression that you care about their feedback :)
```javascript
window.formbricks = {
...window.formbricks,
config: {
// ...
contact: {
name: "Johannes",
position: "Co-Founder",
imgUrl: "https://avatars.githubusercontent.com/u/72809645?v=4",
},
},
};
```
**Sending user data with feedback**
The feedback box is built for in-app experiences. We assume that you already have user properties stored in a session object.
Here is an example of how to pass it to Formbricks. However, it might differ in your specific case.
```javascript
window.formbricks = {
...window.formbricks,
config: {
// ...
customer: {
email: "", // fill dynamically
name: "", // fill dynamically
},
};
},
```
Note: the `email` field must be present in the customer object
**Styling**
You can style the Feedback Box to match your UI. We recommend to at least replace the brand color with your main color.
```javascript
window.formbricks = {
...window.formbricks,
config: {
// ...
style: {
brandColor: "#00c4b8",
},
};
},
```
Here are all variables you can set with the current defaults:
```javascript
style: {
brandColor: "#00c4b8",
borderRadius: "0.4rem",
headerBGColor: "#1e293b",
headerTitleColor: "#111111",
boxBGColor: "#cbd5e1",
textColor: "#0f172a",
buttonHoverColor: "#e2e8f0",
},
```
### Example config
Here is an example of a full config object:
```javascript
window.formbricks = {
...window.formbricks,
config: {
hqUrl: "https://app.formbricks.com",
formId: "cldipcgat0000mn0g31a8pdse",
containerId: "formbricks-feedback-box", // only needed for modal & inline
contact: {
name: "Johannes",
position: "Co-Founder",
imgUrl: "https://avatars.githubusercontent.com/u/72809645?v=4",
},
customer: {
id: "", // fill dynamically
name: "", // fill dynamically
email: "", // fill dynamically
},
style: {
brandColor: "#0E1420",
headerBGColor: "#E5E7EB",
headerTitleColor: "#4B5563",
boxBGColor: "#F9FAFB",
textColor: "#374151",
buttonHoverColor: "#F3F4F6",
},
},
};
```
### 3. Embed
To add the Feedback Box to your UI, you can use different wrappers. Please follow the instructions linked below:
1. <Link href="/docs/wrappers/pop-over">In-app Pop-over</Link>
2. <Link href="/docs/wrappers/modal">Modal</Link>
3. <Link href="/docs/wrappers/inline">Inline</Link>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,14 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { Callout } from "@/components/shared/Callout";
export const meta = {
title: "In-app Interview Prompt",
};
<Callout title="Closed Beta" type="note">
In-app interview prompts are only available in closed beta. Want to become a design partner? Reach out at
hola@formbricks.com
</Callout>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,14 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { Callout } from "@/components/shared/Callout";
export const meta = {
title: "Onboarding Segmentation",
};
<Callout title="Closed Beta" type="note">
Onboarding Segmentation is only available in closed beta. Want to become a design partner? Reach out at
hola@formbricks.com
</Callout>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,178 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import Link from "next/link";
import Image from "next/image";
import NewPMF from "@/images/docs/new-pmf.png";
import ID from "@/images/docs/copy-id.png";
import PmfDummy from "@/components/docs/PmfDummy";
export const meta = {
title: "Product-Market Fit Survey",
};
The Product-Market Fit survey (or Sean Ellis Test) is a method to measure Product-Market Fit.
## Purpose
By assessing how disappointed users would be if they could no longer use your service you get a good idea of how well your current product fits your target market.
Measuring it allows you to optimize it.
## Formbricks Approach
- Higher conversion: In-app surveys **convert significantly better** than email surveys
- **Pre-segment** user base: Only ask users who experienced the value of your product
- **Specific** dashboard: Understand your data right, separate signal from noise by design
- Targeted approach: **Personally address** users with their name (if you have it)
- Measure continuously: Feel the pulse of your user base **consistently**
- No UI clutter: **Natively embed** the survey for best possible UX
- **Never** ask twice: Assure to not survey users twice
## Preview
<div className="max-w-md">
<PmfDummy />
</div>
## Installation
To add the Product-Market Fit Survey to your app, you need to perform these steps:
1. Create new survey at app.formbricks.com
2. Embed JS snippet in `<head>`
3. Configure survey
4. Render in-app
### 1. Create new survey
Create an account at [app.formbricks.com](https://app.formbricks.com/auth/signup)
Then, create a new Product-Market Fit Survey:
<Image src={NewPMF} alt="create pmf survey" quality="100" />
Go to the "Setup instructions" tab and copy the ID:
<Image src={ID} alt="copy survey id" quality="100" />
### 2. Embed Formbricks snippet in `<head>`
Embed the Product-Market Fit Survey script in your HTML `<head>` tag and replace survey ID:
```tsx
<script src="https://cdn.jsdelivr.net/npm/@formbricks/pmf@0.0.9" defer></script>
<script>
window.formbricksPmf = {
...window.formbricksPmf,
config: {
formbricksUrl: "https://app.formbricks.com",
formId: "SURVEY ID HERE", // paste your survey ID here
containerId: "formbricks-pmf", // required to render survey in your page
},
};
</script>
```
All you have to do now is assigning the `containerId` to the div where you want to render your survey (detailed instructions at the bottom):
```html
<div id="formbricks-pmf"></div>
```
### 4. Configure
**Sending user metadata with submission**
The Product-Market Fit Survey is built for in-app experiences. We assume that you already have user properties stored in a session object. It makes sense to send them to Formbricks to enrich the user profile in the user view. Later on, you will be able to create cohorts to survey based on user properties.
Here is an example of how to take metadata from the next.js Session Object and pass it to Formbricks:
```javascript
window.formbricksPmf = {
...window.formbricksPmf,
config: {
// ...
customer: {
email: "", // fill dynamically
name: "", // fill dynamically
},
};
},
```
Note: the `email` field must be present in the customer object
**Styling**
You can style the Product-Market Fit Survey to match your UI. We recommend to at least replace the brand color with your main color.
```javascript
window.formbricksPmf = {
...window.formbricksPmf,
config: {
// ...
style: {
brandColor: "#00c4b8",
},
};
},
```
Here are all variables you can set with the current defaults:
```javascript
style: {
brandColor: "#00c4b8",
borderRadius: "0.4rem",
containerBGColor: "#f8fafc",
containerBGColor: "#f8fafc",
textColor: "#0f172a",
buttonTextColor: "#ffffff",
textareaBorderColor: "#e2e8f0",
},
```
### Example config
Here is an example of a full config object:
```javascript
window.formbricksPmf = {
...window.formbricksPmf,
config: {
formbricksUrl: "https://app.formbricks.com",
formId: "cldetkpre0000nr0hku986hio",
containerId: "formbricks-pmf-survey", // always needed
customer: {
id: "", // fill dynamically
name: "", // fill dynamically
email: "", // fill dynamically
},
style: {
brandColor: "#00c4b8",
borderRadius: "0.4rem",
containerBGColor: "#f8fafc",
containerBGColor: "#f8fafc",
textColor: "#0f172a",
buttonTextColor: "#ffffff",
textareaBorderColor: "#e2e8f0",
},
},
};
```
### 3. Embed
To add the Product-Market Fit Survey to your UI, you can use different wrappers. Please follow the instructions linked below:
1. <Link href="/docs/wrappers/modal">Modal</Link>
2. <Link href="/docs/wrappers/inline">Inline</Link>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,14 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import { Callout } from "@/components/shared/Callout";
export const meta = {
title: "Waitlist Survey",
};
<Callout title="Closed Beta" type="note">
The Waitlist Survey is only available in closed beta. Want to become a design partner? Reach out at
hola@formbricks.com
</Callout>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,25 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
export const meta = {
title: "What are Best Practices?",
};
Best Practices are end-to-end productized methods for managing product. They are designed to make **product-led growth easier**.
A Best Practice consists of two parts:
- A set of **survey questions** / method to determine questions
- A **specifically designed dashboard** to interact with the qualitative data
## Current Best Practices
| Name | Purpose | Status |
| ------------------------- | ------------------------------------------------------------- | ----------- |
| Feedback Box | Gather feedback from users in your app as easily as possible. | Public Beta |
| Product-Market Fit Survey | Continuously masure PMF score to be able to optimize it | Public Beta |
| Onboarding Segmentation | Segment new users as they onboard your service | Closed Beta |
| Waitlist survey | Gather key information about your user base pre-product | Closed Beta |
| In-app Interview Prompt | Invite selected users in-app to book an interview | Up next |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

View File

@@ -1,189 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import Image from "next/image";
import Architecture from "./api-endpoints.png";
import { Callout } from "@/components/shared/Callout";
import { APILayout } from "@/components/shared/APILayout.tsx";
export const meta = {
title: "Core API - Formbricks Open Source Form & Survey Builder",
};
## Why a form API?
We want to empower you to rapidly build exactly the form and survey functionality that you need. An open API is key to achieve that as it gives you access to every single data model within the application. This allows you to replicate the entire functionality of [Formbricks HQ](/formbricks-hq) in your own app using the API.
## Architecture
Especially large organisations with multiple teams suffer from scatterd qualitative data. This is why we baked in scaleability right from the start. The data models are structured as follows:
<Image src={Architecture} alt="Data model of open source form tool" className="rounded-lg" />
## Auth: Personal API key
The API requests are authorized with a personal API key. This API key gives you the same rights as if you were logged in at formbricks.com - **don't share it around!**
### How to generate an API key
1. Go to your profile at [hq.formbricks.com](https://hq.formbricks.com/app/me/settings).
2. Select “Add key”.
3. Assign it any label (this is just for you).
4. Copy the key. You wont be able to see it again.
<Callout title="Store API key safely" type="warning">
Anyone who has your API key has full control over your account. For security reasons, you cannot view the
API key again.
</Callout>
### Delete a personal API key
1. Go to your profile at [hq.formbricks.com](https://hq.formbricks.com/app/me/settings).
2. Find the key you wish to revoke and select “Delete”.
3. Your API key will stop working immediately.
## User
### Find current user
<APILayout
method="GET"
url="/users/me"
description="Get the current logged in user."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{ label: "tba", type: "tba", description: "tba" },
{ label: "tba", type: "tba", description: "tba" },
]}
responses={[
{ color: "green", statusCode: "tba", description: "tba" },
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
## Team
### Find memberships
<APILayout
method="GET"
url="/memberships"
description="Get all of my team memberships."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{ label: "tba", type: "tba", description: "tba" },
{ label: "tba", type: "tba", description: "tba" },
]}
responses={[
{ color: "green", statusCode: "tba", description: "tba" },
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
### Get specific team
<APILayout
method="GET"
url="/teams/[teamId]"
description="Get a specific team by team ID."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{ label: "tba", type: "tba", description: "tba" },
{ label: "tba", type: "tba", description: "tba" },
]}
responses={[
{ color: "green", statusCode: "tba", description: "tba" },
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
## Forms
### Get all forms of a team
<APILayout
method="GET"
url="/teams/[teamId]/forms"
description="Get all forms of a team by team ID."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{ label: "tba", type: "tba", description: "tba" },
{ label: "tba", type: "tba", description: "tba" },
]}
responses={[
{ color: "green", statusCode: "tba", description: "tba" },
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
### Create new form
<APILayout
method="POST"
url="/teams/[teamId]/forms"
description="Create a new form"
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{ label: "label", type: "string", description: "The name you want to give your form.", required: true },
{
label: "schema",
type: "JSON",
description: "A valid Formbricks schema to provide provide context for the form data.",
},
]}
responses={[
{ color: "green", statusCode: "tba", description: "tba" },
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
## Submissions
### Get all submission of a form
<APILayout
method="GET"
url="/teams/[teamId]/forms/[formId]/submissions"
description="Request all submissions of a form by ID."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{ label: "tba", type: "tba", description: "tba" },
{ label: "tba", type: "tba", description: "tba" },
]}
responses={[
{ color: "green", statusCode: "tba", description: "tba" },
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
### Create new submission
<APILayout
method="POST"
url="/capture/forms/[formId]/submissions"
description="Add a new submission to a form by form ID."
queries={[{ label: "apiKey", type: "string", description: "Your API key" }]}
bodies={[
{
label: "customerId",
type: "string",
description: "The customer/user you want to link the submission to.",
},
{
label: "data",
type: "JSON",
description: "The content of the submission.",
},
]}
example="hello"
responses={[
{
color: "green",
statusCode: "200",
description: "tba",
example: "{ // Response }",
},
{ color: "brown", statusCode: "tba", description: "tba" },
]}
/>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,99 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import Schema from "./data-visualisation-open-source-survey-builder.png";
import NoSchema from "./no-schema-visualisation-of-open-source-data-form-builder-creator-webform.png";
import Question from "./schema-open-source-form-creator-web-form-builder.png";
export const meta = {
title: "Schema Open-source forms & survey infrastructure",
};
## What is a schema?
A schema is like a manual for a form: It provides the context of the form including the questions, all answer options, information about pages and more. Essentially, it is the skeleton of your form stored in a .JSON file.
## Why are schemas helpful?
A schema is essential to get a full picture of the data you are collecting. Here is a simple example. Lets say you have a form with one question like this:
<div className="grid md:grid-cols-2 gap-4">
<Image
className=""
src={Question}
alt="Open Source Form with Question about favorite food"
className="rounded-lg"
/>
<div className="mt-2">
```json
<Radio
name="fav-food"
label="What's your favorite food?"
help="Allday, every day!"
options={["Sushi", "Pasta", "Pizza"]}
/>
```
</div>
</div>
If you POST only the data to an API endpoint, it looks like this:
```json
{
"submission": {
"fav-food": "Pasta"
},
```
If you POST the data along with the schema, it looks like this:
```json
{
"submission": {
"fav-food": "pasta"
},
"schema": {
"type": "form",
"config": {},
"children": [
{
"type": "radio",
"name": "fav-food",
"label": "What's your favorite food?",
"options": ["Sushi", "Pasta", "Pizza"]
}
]
}
}
```
Without the schema, a visualisation of your data looks like this:
<Image src={NoSchema} alt="Open Source Form with Question about favorite food" className="rounded-lg" />
As you can see, the question and answer options which were not selected are missing. Over time, when more submissions with different values come in, the visualisation will get more complete. However, when respondents can skip this question it will be challenging to make correct statements about this data point.
<Callout title="Inconsistent data" type="warning">
The lack of a schema almost always leads to **inconsistent data.**
</Callout>
With the schema, the visualisation looks like this:
<Image src={Schema} alt="Open Source Form with Question about favorite food" className="rounded-lg" />
As you can clearly see, this visualisation keeps track of all answer options as well as the initial question. The quality of your decisions will improve, especially over the course of several surveys.
### Why does it work on Typeform, Jotform, etc.?
If you are using standalone form builder like Typeform, Jotform or Tally they handle the schema internally. When you custom build your form functionality or use a Backend-as-a-Service provider like Formspree you should deal with schemas to get a full picture of your data. Or let us do it 👇
### Formbricks React 🤝 Formbricks HQ
Our React Form Library auto-generates a schema out of the form you have built. On submit it sends it over to the Formbricks HQ along with the submission data. Formbricks HQ understands the schema and can display your data correctly.
<Callout title="Forms how they should be" type="note">
With Formbricks you get the level of integration of a custom-coded solution with the speed and ease of a
SaaS tool 🤍
</Callout>
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,56 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import Image from "next/image";
import Step1 from "./step-1-send-web-form-to-email-open-source.png";
import Step2 from "./step-2-select-email-survey-response-to-email-send.png";
import Step3 from "./step-3-add-email-to-send-form-data-to-open-source-alternative.png";
import Step4 from "./step-4-set-active-to-send-survey-data-via-mail-to-myself-open-source.png";
export const meta = {
title: "Email Notifications (UI) - Open-source Forms & Surveys",
};
You can send your form and survey data to your email address. To do so you can setup an Email Pipeline in your form settings.
## Send form data to email
### Setup
You need to have a form created to add a data pipeline to it.
### Step 1: Add Pipeline
In the top bar, select “Pipelines”. Click on “Add Pipeline” in the top right corner:
<Image src={Step1} className="rounded-lg" alt="Step 1 of sending form data to your email address" />
### Step 2: Select type of Pipeline
Select Email Notification. You can also set up a custom [Webhook](/docs/formbricks-hq/ui/webhooks).
<Image src={Step2} className="rounded-lg" alt="Step 2 of best webform to email tool" />
### Step 3: Configure settings
To setup your Pipeline you need to fill out two fields:
**Pipeline label:** Give it a name, this is just for you
**Email address:** Type in your email address
Then select “Create”.
<Image src={Step3} className="rounded-lg" alt="Step 3 of how to send form to email" />
### Step 4: Make sure its active
Congrats, you have created your email pipeline! Make sure it is set to “**Active**”.
<Image
src={Step4}
className="rounded-lg"
alt="Step 4 of sending survey data form open source survey to your email"
/>
From now on you will receive an email with the form content whenever someone submits your form. To deactive it, just turn it off. You can also delete it anytime.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,60 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import Image from "next/image";
import Step1 from "../email-notifications/step-1-send-web-form-to-email-open-source.png";
import Step2 from "../email-notifications/step-2-select-email-survey-response-to-email-send.png";
import Step3 from "./step-3-send-form-data-webhook-open-source.png";
import Step4 from "./step-4-webhook-survey-data-opensource.png";
export const meta = {
title: "Webhooks (UI) - Open source Forms & Surveys",
};
You can send your form and survey data to a destination of your choice via a Webhook. To do so you can set up a Webhook Pipeline in your form settings.
## Send form data with Webhook
### Setup
You need to have a form created to add a data pipeline to it.
### Step 1: Add Pipeline
In the top bar, select “Pipelines”. Click on “Add Pipeline” in the top right corner:
<Image src={Step1} className="rounded-lg" alt="Step 1 of sending form data to your email address" />
### Step 2: Select type of Pipeline
Select Webhook. You can also set up an [Email Notification](/docs/formbricks-hq/ui/email-notifications).
<Image src={Step2} className="rounded-lg" alt="Step 2 of best webform to email tool" />
### Step 3: Configure settings
To setup your Webhook you need to fill out three fields:
**Webhook label:** Give it a name to know what this is for.
**Endpoint URL:** Copy your endpoint URL here. This is where the webhook sends the form data to.
**Secret**: To authenticate the data transmission, add a secret. You can generate one [here](https://www.lastpass.com/features/password-generator) or just type something in.
<Image src={Step3} className="rounded-lg" alt="Step 3 of how to send form to email" />
Then select “Create”.
### Step 4: Make sure its active
Congrats, you have created your webhook pipeline! Make sure it is set to “**Active**”.
<Image
src={Step4}
className="rounded-lg"
alt="Step 4 of sending survey data form open source survey to your email"
/>
From now on the webhook will be triggered whenever someone submits your form. All form data will be sent to the
destination.
To deactive it, just turn it off. You can also delete it anytime.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,13 +1,12 @@
import { Layout } from "@/components/docs/Layout";
import HeroAnimation from "./open-source-tool-for-form-and-survey-overview.png";
import Image from "next/image";
import HeroAnimation from "@/components/shared/HeroAnimation.tsx";
export const meta = {
title: "Formbricks Open-source forms & survey toolbox",
title: "Formbricks Experience Management for B2B SaaS",
};
Modular, customizable, extendable. We're building all essential form functionality on an open platform.
Natively embed qualitative user research into your B2B SaaS. Leverage Best Practices for user discovery to increase Product-Market Fit.
<Image src={HeroAnimation} alt="HeroAnimation" />
<HeroAnimation />
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,36 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
export const meta = {
title: "How Formbricks works",
};
Formbricks has two sides: The end-user facing surveys and the analysis dashboards.
## End-user facing surveys
The surveys are also split up in two elements: The content and the wrapper.
While you will be able to freely design your surveys later on, we start with Best Practices of managing user experiences.
### Best Practices
Best Practices are more than mere survey templates. They are end-to-end productized methods for managing product. Its designed like that to make product-led growth easier.
### Wrappers
Wrappers are different ways to put surveys in front of your users: In-app pop-ups, inline surveys, email surveys, standalone surveys with a link to share, etc.
## Analysis Dashboards
The dashboards are specifically designed for each Best Practice. Instead of a generic visualisation of aggregated data we focus on enabling acting on insights. A few examples:
**Feedback Box dashboard:** Built for a quick and individualized reaction on Feedback
**Product-Market Fit dashboard:** Designed to build conviction for upcoming product decisions.
**Interview Prompt dashboard:** Designed to schedule and manage 1:1 interviews with users
… you get the idea. Lets have a closer look! |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,22 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
export const meta = {
title: "How will we achieve this?",
};
The goal is clear: Build the last form tool humanity needs. What does such a solution have to look like?
### Modular
Form needs differ widely but a one-size-fits all monolith would fit no one. It would be slow and bloated. Only when it's possible to compose exactly the solution you need with the performance you expect we can compete with current solutions.
### Customizable
In many product decisions you cannot have it both ways. We have to build opionated to make progress. We always choose what we deem the best option based on over 10 years of experience building forms and form-based products. If you prefer it the other way, just change it up. Our code is freely accessible and licensed accordingly.
### Extendable
Similarily, we cannot offer a solution for every niche and edge case. And we don't have to. Running open source allows you to go 95% of the way with our tech and build a thin integration layer to make it fit your need perfectly.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,12 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
export const meta = {
title: "Quick Start",
};
We're sporting a mono repository to make it as easy as possible to get you up and running with the Bricks.
Please head over to [Github](https://github.com/formbricks/formbricks), clone the code and get started.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -5,32 +5,12 @@ export const meta = {
title: "What is Formbricks?",
};
On a high-level, form functionality can be divided into five groups: Form creation, usage analytics, data handling, data insights and data actions. Over time, we will offer solution bricks for each of these groups.
🚀 Formbricks is a micro-survey tool built for **product-led growth.**
### Form Creation Bricks
🤓 We've productized **Best Practices** to gather, analyze and act on qualitative data.
There are two ways to create a form: Code and No Code. We will empower you to create forms both ways as well as hybrid (start with Code, update with No Code).
🧘 Formbricks is built to be natively integrated into digital products. **No more UI clutter.**
We're kicking it off with a [Library for React.js](/react-form-library) and follow up with a fully compatible No Code builder. Your engineers will fly through form creation and can embed them natively into the product, while your operations teams can control the content of the form. Finally, no more Jira tickets to fix a typo.
### Usage Analytics
You want to know how respondents interact with your form or survey. How many complete the survey? Where do they drop-off? What combination of questions works best? We'll provide key insights natively and allow you to hook up your favorite product analytics tool (i.e. [PostHog](https://posthog.com)).
### Data Handling Bricks
Creating a form is only the first step. You need a destination for your submissions. We offer an [API endpoint](/core-api) where you can submit your pre-existing forms to. Within minutes you can start receiving submissions and view them in your [dashboard](/formbricks-hq).
Additionally, we're offering [email notifications](/email), [webhooks](/webhooks) and integrations into all the great tools you're already using. Control the flow of your qualitative data in one place.
### Data Insight Bricks
To get the most out of your qualitative data, you will perform an in-depth analysis of your submissions. While we are busy building out the core tech, we enable you to view and export data as easily as possible. Down the line, assisting in the data analysis is where the magic happens 🧚
### Data Action Bricks
Similarily, you want to act on the qualitative insights about your customer or employee relationship. While you can partially do that with 3rd party tools, you gain real leverage when the flow from form creation to submission analysis to action is integrated intelligently.
Imagine your form tool knows a customers shopping history, the previous NPS rating and understands the sentiment of the micro-survey this customer just filled out on your webshop. It can automatically send out a contextualized voucher for a product the customer is likely to buy. But let's not spill the beans here :)
🤍 Formbricks is **open-source**. Control the data you gather. Easily comply with all privacy regulation.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,28 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
export const meta = {
title: "Why Formbricks?",
};
With all the form tools out there, why would we build another one?
## Why though?
It doesn't matter what products we've built over the past couple of years, forms always played an important role. While there are great solutions out there, you very quickly reach the barrier of what's possible. They all do one thing well, but when it comes to leveraging qualitative data, one thing isn't enough.
Over time, this leads to a collection of island solutions in different teams as well as creative approaches to hack form functionality together. Data is scattered everywhere, maintenance is costly and valuable insights are not used to their full potential.
### Forms bridge 🧠 and 💻
Until Elon ships the Neuralink brain-machine interface, forms are our best bet to get information out of brains into computers. In a business context, a 🧠 is either a customer or an employee. The interface to these very important stakeholders should run as smoothly as possible, almost as if it was built on one platform 😉
### Stop rewriting existing code
A common idea is to just "build it ourselves". Forms and surveys appear to be quick to build but once you get started you notice that it gets complicated quickly. Validation, spam protection, data pipelines into different databases and 3rd party services, schemas or supported data analysis are just a few of the things you want, but don't want to build yourself. And you shouldn't, someone already wrote that code, you just cannot use it. This is changing with Formbricks.
### The last form tool
The goal is clear: Build the last form tool humanity needs. But how?
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -0,0 +1,21 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
export const meta = {
title: "Why is Formbricks better?",
};
Formbricks is **not** a generic form builder.
It's designed to **build user research into your product.**
| Form Builders | **Formbricks** |
| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| _Spray and pray_ | Connect analytics and pre-segment based on usage |
| _Submission-focussed: Impossible to build on previous submissions_ | User-focussed: Access all responses per user, add user properties, gather full picture. |
| _Stiff UI_ | Use your UI or use our highly customizable components |
| _Built for everyone who needs forms_ | Built for founders and product managers |
| _Generic form templates_ | Best Practices for product management: In-app interview prompt, onboarding segmentation, etc. |
| _No data ownership_ | Full data ownership |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,50 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
export const meta = {
title: "Form Wrapper - Formbricks React Form Library",
};
The form wrapper is the envelope of you form: you put all important information inside and write on the back what happens with the envelope and its content.
In code terms, this means that it is up to you to decide what happens when the respondent clicks on the Submit button of your form. Formbricks React allows to pass a function to onSubmit which will be executed when the form is submitted.
### Logging to browser console
In this example, were handing over the form _data_ and the form _schema_ to the onSubmit function. In the function itself we use the _data_ and the _schema_ and log it in the browser console:
```jsx
onSubmit={({ data, schema }) => console.log("data:", data, "schema:", schema)}
```
### Sending to API endpoint
Here were sending the data to an API endpoint to receive and display out submission:
```jsx
<Form
onSubmit={({ data }) => {
fetch("API ENDPOINT URL", {
method: "POST",
body: JSON.stringify(data),
headers: {
Accept: "application/json",
},
});
}}>
{/* YOUR FORM */}
</Form>
```
### What else would you like to do with your data?
[Join our Discord to suggest features 🤸](https://formbricks.com/discord)
### Props & Attributes
| Prop | Type | Default | Description |
| -------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| onSubmit | Function | `()=>{}` | Gets passed on object with `{data, schema, event}` and is triggered when the form gets submitted without errors |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -1,105 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import SimpleForm from "./simple-form-basic-theme-formbricks-react-form-survey-library-builder-v1.png";
import LogData from "./data-output-console.png";
export const meta = {
title: "Getting started - Formbricks React Form Library",
};
This is a step-by-step guide on how to get started with Formbricks React.
### Preparation: Create React App
To use Formbricks React, you need a React application. If you don't have your application already, please follow these guides to either create a React or a Next.js app:
- [Create new React app](https://reactjs.org/docs/create-a-new-react-app.html)
- [Create new Next.js app](https://nextjs.org/docs/api-reference/create-next-app)
### 1. Install Formbricks React
Install Formbricks React using the package manager of your choice:
```bash
npm install -s @formbricks/react
# or
yarn add @formbricks/react
# or
pnpm add @formbricks/react
```
### 2. Create new form component
Since React is based on components, we will create a new component for your form. To do so, create a file called `Form.jsx` - if you work with TypeScript you need to change the suffix to `.tsx`.
### 3. Import form components
To be able to use Formbricks React in your file, you need to import the components that you intend to use. [Here is an overview](/docs/react-form-library/work-with-components) of all available components.
For a simple sign up form we import the following:
```jsx
import { Form, Text, Textarea, Submit } from "@formbricks/react";
# or
yarn add @formbricks/react
# or
pnpm add @formbricks/react
```
<Callout title="Import only what you need" type="warning">
Currently, all components you import will be part of your production build. Please only import components
that youre using for the best possible performance.
</Callout>
### 4. Code your form
Now were getting to the fun part: Coding your form. This is the full form code you can copy and play around with. Below we go through it step-by-step:
```jsx
import { Form, Text, Textarea, Submit } from "@formbricks/react";
import "@formbricks/react/styles.css";
export default function WaitlistForm() {
return (
<Form onSubmit={({ data, schema }) => console.log("data:", data, "schema:", schema)}>
<Text name="firstname" label="What's your first name?" validation="required" />
<Text name="lastname" label="What's your last name?" />
<Textarea name="about" label="About you" help="Please keep it short" />
<Submit name="submit" label="Submit" />
</Form>
);
}
```
This form imports the default formbricks theme for styling, we cover [styling](/docs/react-form-library/style-css) later.
Your browser window should look like this now:
<Image src={SimpleForm} alt="Unstyled form created with best react form library" className="rounded-lg" />
### 5. Test if it works
To test if the form works as planned open the browser console and fill out the form.
The console should show you the data and the schema of your form:
<Image
src={LogData}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
### Whats next?
Congratulations, your React form works!
To get to the desired outcome, there are three more things on your list:
[→ Receive and manage form submissions](/docs/react-form-library/link-formbricks-hq)
[→ Explore all input types and how props define them](/docs/react-form-library/work-with-components)
→ Learn how to style the form with [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind)
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,74 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import FindIcon from "./icon-name-react-library-form-builder.png";
export const meta = {
title: "Icons - Formbricks React Form Library",
};
Icons give forms and surveys not only a professional look & feel, they increase the usability. Formbricks React supports icons in several locations throughout the form.
### Choosing an icon library
In the first step you have to decide which library you like. We like:
- [HeroIcons](https://heroicons.com/),
- [FeatherIcons](https://feathericons.com/) (beautiful but limited),
- [React Icons](https://react-icons.github.io/react-icons/). (huge collection)
### Installing library package
Once you picked yours you have to add it to your repository, e.g. HeroIcons:
```jsx
npm install @heroicons/react
```
### Importing icons
Next you have to import the icons you want to use them in your form:
```jsx
import { PlusIcon } from "@heroicons/react/24/outline";
# or several at once
import { ChatBubbleOvalLeftEllipsisIcon, EnvelopeIcon } from "@heroicons/react/24/solid";
```
If you paid close attention you noticed that we imported `PlusIcon` from the `outline` folder and the latter two from the `solid` folder. You can find the name of the icon you'd like to import on the respective website:
<Image
src={FindIcon}
alt="Illustration of error message and validation handling in best form react lib"
className="rounded-lg"
/>
Now you're ready to use them!
### Using icons
At this early stage, we only support icons in the submit button. You add it **before** and **after** the button text.
Before the button text:
```jsx
<Submit label="Submit" PrefixIcon={EnvelopeIcon} />
```
After the button text:
```jsx
<Submit label="Submit" SuffixIcon={PlusIcon} />
```
### Props & Attributes
| Prop | Type | Default | Description |
| ---------- | ---- | ------- | --------------------------- |
| PrefixIcon | SVG | - | Icon displayed before label |
| SuffixIcon | SVG | - | Icon displayed after label |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,158 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./Checkbox-input-form-survey-react-lib-easy-build-forms-fast-validation-multi-step.png";
export const meta = {
title: "Checkbox - Formbricks React Form Library",
};
The checkbox input uses [HTML's checkbox input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox) and can display one or many options to a user. It's a great way to allow users to select multiple items from a list. Formbricks supports single and multiple checkboxes.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Checkbox } from "@formbricks/react";
<Checkbox name="terms" />;
```
## Single Checkbox
By default the checkbox input will render a single checkbox returning a `boolean` value:
```jsx
import { Checkbox } from "@formbricks/react";
<Checkbox
name="newsletter"
label="Monthly Newsletter"
help="Would you like to receive our newsletter?"
validation="accepted"
/>;
```
## Multiple checkboxes
There are two ways to add several options to your checkbox input, both using the `options` attribute.
### Options: Array of values
The options attribute can handle an array of values which are interpreted both as label and value.
```jsx
<Checkbox
name="toppings"
label="What do you like on your Pizza?"
help="Take what you like"
options={["Pineapple", "Ananas", "Piña"]}
/>
```
### Options: Array of objects
The options attribute can also handle an array of objects containing label/value pairs. This allows for differences between the label and the data stored. You can also add an optional config object:
```jsx
<Checkbox
name="allergies"
label="What are you allergic to?"
help="Tick all the boxes."
options={[
{
label: "Dogs",
value: "dogs",
config: {
disabled: true,
},
},
{
label: "These nuts",
value: "nuts",
},
{
label: "Bullshit",
value: "bs",
},
]}
/>
```
## Props & Attributes
| Prop | Type | Default | Description | |
| ---------------- | -------------------- | ------- | ------------------------------------------- | ---------------------------------------------------- |
| options | Array | - | Contains the options in your checkbox input | |
| label | String | - | The label of the checkbox input. | |
| legendClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionsClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-legend | The legend (often a question) |
| formbricks-help | The help text itself. |
| formbricks-options | A wrapper around all options. |
| formbricks-option | A wrapper around each option. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself, here the checkbox button. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Checkbox
name="toppings"
label="What do you like on your Pizza?"
help="Take what you like"
options={["Pineapple", "Ananas", "Piña"]}
legendClassName="font-bold"
optionClassName="bg-slate rounded-sm"
/>
```
### Options-specific props to style it
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ---------------- | -------------------- | --------- | -------------------- | ---------------------------------------------------- |
| legendClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionsClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,83 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "../style-css/html-classes-of-formbricks-react-form-library-to-custom-style-surveys-and-forms.png";
export const meta = {
title: "Email Input - Formbricks React Form Library",
};
The `Email` input uses HTML's [native email input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email). It allows a user to enter an email.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Email } from "@formbricks/react";
<Email name="email" />;
```
In most cases, it looks something like this:
```jsx
import { Email } from "@formbricks/react";
<Email name="email" label="What's your email?" placeholder="Email" />;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------ |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your email field with adding CSS to the section classes. This is how the classes are named:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Email name="email" label="What's your email?" inputClassName="bg-slate-800 my-5" />
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,94 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./Number-input-best-easy-react-form-library-2023-forms-survey.png";
export const meta = {
title: "Number Input - Formbricks React Form Library",
};
The `Number` input uses HTML's [native number input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number). It allows a user to enter a single integer or decimal value.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Number } from "@formbricks/react";
<Number name="age" />;
```
In most cases, it looks something like this:
```jsx
import { Number } from "@formbricks/react";
<Number name="age" label="How old are you?" placeholder="42" min="1" max="130" step="1" />;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------------------------------------------ |
| min | Number | - | The input has to be at least X |
| max | Number | - | The input cannot be higher than Y |
| step | Number | auto | Specifies the granularity that the value must adhere to when increasing / decreasing |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your number field with adding CSS to the section classes. This is how the classes are named:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Number
name="age"
label="How old are you?"
placeholder="42"
min="1"
max="130"
step="1"
inputClassName="font-bold"
/>
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,91 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./Password-input-easy-react-form-library-build-forms-surveys-fast.png";
export const meta = {
title: "Password Input - Formbricks React Form Library",
};
The `Password` input uses HTML's [native password input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/password). It allows a user to enter a password.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Password } from "@formbricks/react";
<Password name="password" />;
```
In most cases, it looks something like this:
```jsx
import { Password } from "@formbricks/react";
<Password
name="password"
label="Password"
help="Enter secure password"
placeholder="ilikecoldcoffee"
validation="required"
/>;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------ |
| minLength | Number | 0 | Limits min length accepted in the field |
| maxLength | Number | 524288 | Limits max length accepted in the field |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Password name="password" label="Password" validation="required" outerClassName="bg-slate-800" />
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,85 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./Phone-react-library-for-surveys-and-form-build-fast-and-easy.png";
export const meta = {
title: "Phone Input - Formbricks React Form Library",
};
The `Phone` input uses HTML's [native tel input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/tel). It allows a user to enter a telephone number.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Phone } from "@formbricks/react";
<Phone name="phone" />;
```
In most cases, it looks something like this:
```jsx
import { Phone } from "@formbricks/react";
<Phone name="phone" label="Phone" help="Enter your phone number." placeholder="+1 123 444 567" />;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------ |
| minLength | Number | 0 | Limits min length accepted in the field |
| maxLength | Number | 524288 | Limits max length accepted in the field |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Phone name="phone" label="Phone" outerClassName="bg-slate-800" />
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,180 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import Exp1 from "./radio-boxes-exp-1-form-survey-best-react-library.png";
import Exp2 from "./radio-boxes-exp-2-best-react-library-survey-forms.png";
import Exp3 from "./radio-boxes-exp-3-forms-and-survey-form-builder.png";
import Styling from "./Radio-CSS-custom-styling-react-form-library-survey.png";
export const meta = {
title: "Radio Buttons - Formbricks React Form Library",
};
The radio input uses [HTML's native radio](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio) inputs to allow a user to select one value from a set of options.
The radio input needs two props:
- `name`
- `options`
## Options attribute
### Options: Array of values
The options attribute can handle an array of values which are interpreted both as label and value.
```jsx
import { Radio } from "@formbricks/react";
<Radio
name="food"
label="What's your favorite food?"
help="Only choose one"
options={["Sushi", "Pasta", "Pizza"]}
/>
# data output
label: Sushi, value: Sushi,
label: Pasta, value: Pasta,
label: Pizza, value: Pizza
```
<Image src={Exp2} alt="Screenshot of Radio Question built with fast React Form Lib" className="rounded-lg" />
### Options: Array of objects
The options attribute can also handle an array of objects containing label:value pairs. This allows for differences between the label and the data stored. You can also disable options:
```jsx
<Radio
name="germany"
label="What's the capital of Germany?"
help="Find the right one"
options={[
{
label: "Kiel",
value: "kiel",
config: {
disabled: true,
},
},
{
label: "Berlin",
value: "berlin",
},
{
label: "Bonn",
value: "bonn",
},
]}
/>
# data output
label: Kiel, value: kiel,
label: Berlin, value: berlin,
label: Bonn, value: bonn
```
<Image
src={Exp3}
alt="Screenshot of Radio Question built with best React Survey Lib"
className="rounded-lg"
/>
### Options: No Options
You don't have to add options to your radio button. In this case the label of the input field is also used as the label for the only option and the data stored:
```jsx
<Radio name="agree" label="Do you agree?" help="Just a question" />
# data output
label: "Do you agree?", value: "Do you agree?"
```
<Image src={Exp1} alt="Screenshot of Radio Question built with best React Form Lib" className="rounded-lg" />
## Props & Attributes
| Prop | Type | Default | Description | |
| ---------------- | -------------------- | ------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| options | Array | - | Contains the options in your radio input | |
| label | String | - | The label of the radio input. <br/>With no `option` attribute it's also the stored value. | |
| legendClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionsClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={Styling}
alt="Styling of Radio Question built with best React Form Library"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-legend | The legend (often a question) |
| formbricks-help | The help text itself. |
| formbricks-options | A wrapper around all options. |
| formbricks-option | A wrapper around each option. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself, here the radio button. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Radio
name="food"
label="What's your favorite food?"
help="Only choose one"
options={["Sushi", "Pasta", "Pizza"]}
legendClassName="font-bold"
optionClassName="bg-slate rounded-sm"
/>
```
### Options-specific props to style it
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ---------------- | -------------------- | --------- | -------------------- | ---------------------------------------------------- |
| legendClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionsClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| optionClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,90 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./Search-input-react-form-library-survey-forms-validation-multi-step-forms.png";
export const meta = {
title: "Search Input - Formbricks React Form Library",
};
The `Search` input uses HTML's [native search input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/search). It allows a user to enter a search term and is interpreted differently than the normal `text` input from the browser, e.g. it adds a little `x` inside the input field to remove the input again.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Search } from "@formbricks/react";
<Search name="search" />;
```
In most cases, it looks something like this:
```jsx
import { Search } from "@formbricks/react";
<Search name="search" placeholder="Search..." label="Search" />;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------ |
| minLength | Number | 0 | Limits min length accepted in the field |
| maxLength | Number | 524288 | Limits max length accepted in the field |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Search
name="search"
placeholder="Search..."
label="Search"
innerClassName="border-slate-700 border-2 rounded-full"
/>
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,52 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
export const meta = {
title: "Submit Button - Formbricks React Form Library",
};
The submit button component is very straight forward:
```jsx
import { Submit } from "@formbricks/react";
<Submit name="submit" label="Submit" />;
```
To keep it working make sure that there is **only one Submit button** per form.
### Adding an icon
You can add icons **before and after** the button text:
```jsx
import { Submit } from "@formbricks/react";
<Submit label="Submit" PrefixIcon={BeakerIcon} SuffixIcon={BeakerIcon} />;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ---------- | ---- | ------- | --------------------------- |
| PrefixIcon | SVG | - | Icon displayed before label |
| SuffixIcon | SVG | - | Icon displayed after label |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ---------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | no | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,85 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "../style-css/html-classes-of-formbricks-react-form-library-to-custom-style-surveys-and-forms.png";
export const meta = {
title: "Text Input - Formbricks React Form Library",
};
The `Text` input uses HTML's [native text input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text). It allows a user to enter a single line of text.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { Text } from "@formbricks/react";
<Text name="firstname" />;
```
In most cases, it looks something like this:
```jsx
import { Text } from "@formbricks/react";
<Text name="firstname" label="What's your first name?" placeholder="First Name" validation="required" />;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------ |
| minLength | Number | 0 | Limits min length accepted in the field |
| maxLength | Number | 524288 | Limits max length accepted in the field |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Text name="firstname" label="What's your first name?" outerClassName="bg-slate-800 my-5" />
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,92 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "../style-css/html-classes-of-formbricks-react-form-library-to-custom-style-surveys-and-forms.png";
export const meta = {
title: "Textarea Input - Formbricks React Form Library",
};
The `textarea` input uses HTML's [native textarea input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea) . It allows a user to enter multiple lines of text and is resizable in most browsers.
Like all other inputs it needs a name prop as an unique identifier:
```jsx
import { Textarea } from "@formbricks/react";
<Textarea name="description" />;
```
In most cases, it looks something like this:
```jsx
import { Textarea } from "@formbricks/react";
<Textarea
name="firstname"
label="Tell us about you:"
placeholder="When I was young..."
validation="required"
/>;
```
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ----------------------------------------------- |
| minLength | Number | 0 | Limits min length accepted in the field |
| maxLength | Number | 524288 | Limits max length accepted in the field |
| placeholder | String | - | Placeholder before respondent clicks into field |
| cols | Number | - | Number of cols (width) of the textarea |
| rows | Number | - | Number of rows (height) of the textarea |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<Text name="firstname" label="What's your first name?" outerClassName="bg-slate-800 my-5" />
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,83 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./URL-field-input-best-easy-react-form-librari-hook-form-survey.png";
export const meta = {
title: "URL Input - Formbricks React Form Library",
};
The `URL` input uses HTML's [native url input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url). It allows a user to enter a url.
Like all other inputs it needs a `name` prop as an unique identifier:
```jsx
import { URL } from "@formbricks/react";
<URL name="url" />;
```
<Callout title="Consider using Text input" type="note">
The reason there is an URL input in HTML is the native URL validation. Since Formbricks offers URL
validation out of the box you can remove unneccessary complexity by using the [Text
input](/docs/react-form-library/input-text).
</Callout>
### Props & Attributes
| Prop | Type | Default | Description |
| ----------- | ------ | ------- | ------------------------------------------------ |
| minLength | Number | 0 | Limits min length accepted in the field |
| maxLength | Number | 524288 | Limits max length accepted in the field |
| placeholder | String | - | Placeholder before respondent clicks into field. |
### Universal props all inputs have
| Prop | What is it? | Required? | Shown to respondent? | Comment |
| ----------------- | --------------------------------------- | --------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name | name of the field | yes | no | It is not shown to respondents but important as a unique identifier to understand which field holds what content. You cannot have two fields with the same name. |
| label | label of the field | yes | yes | The label above the input |
| help | help text | no | yes | You can add a little help text to each field to provide more detail on how to fill out the field. |
| validation | determines how field input is validated | no | depends on field input | If you want to validate the content of a field before the form is sent, you can do so with the validation prop. [read more](/docs/react-form-library/validation-errors) |
| id | own identifier for input | no | no | To target your input with css or javascript directly |
| outerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| wrapperClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| innerClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| inputClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| helpClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messagesClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
| messageClassName | append styling class | no | - | [read more](/docs/react-form-library/style-tailwind) |
### Styling with CSS
You can style your field with adding CSS to the pre-assigned classes. This is how the classes are assigned:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### Styling with Tailwind
You can also use Tailwind to extend the classes, like so:
```jsx
<URL name="url" label="Company website" outerClassName="bg-slate-800 my-5" />
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,73 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Fence } from "@/components/shared/Fence";
import Image from "next/image";
import StyleClasses from "./sampleform.png";
export const meta = {
title: "Building React forms just got easy",
};
Every developer works with forms, few like their experience. Building Forms, especially in React, can be pretty annoying. State management, validation, form components, accessibility, internationalization and performance are all things you have to deal with, but don't really want to.
We make building - and maintaining - forms easier than ever in the world of React.
### Example
```jsx
import { Form, Text, Email, Checkbox, Submit } from "@formbricks/react";
import "@formbricks/react/styles.css";
export default function WaitlistForm() {
return (
<Form onSubmit={({ data, schema }) => console.log("data:", data, "schema:", schema)}>
<Text name="name" label="What's your name?" validation="required" />
<Email
name="email"
label="What's your email address?"
placeholder="you@example.com"
validation="required|email"
/>
<Checkbox
name="terms"
label="Terms & Conditions"
help="To use our service, please accept."
validation="accepted"
/>
<Submit label="Let's go!" />
</Form>
);
}
```
<div className="grid grid-cols-1 sm:grid-cols-2">
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
</div>
### Why is this easier already?
- One easy to use syntax for all input types
- HTML & non-HTML input types available out of the box
- Easily maintainable with component-based approach
- All characteristics adjustable via props
- Automatic schema generation
### What is to come?
- Conditional logic
- Multi-page forms
- Accessibility
- Internationalization
- Form Templates (content & styles)
### Shoutout
The Formbricks React Library is built on top of [React Hook Form](https://react-hook-form.com/) to make from their data handling and performance optimizations.
The developer experience is inspired by the great [FormKit for Vue.js](https://formkit.com/) Library.
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,70 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import Image1 from "./image1-formspree-open-source-alternative-for-free-opensource.png";
import Image2 from "./image2-formspree-open-source-alternative-for-free-opensource.png";
import Image3 from "./image3-formspree-open-source-alternative-for-free-opensource.png";
export const meta = {
title: "Receive and manage submissions - Link with Formbricks HQ",
};
Creating forms is only half of the work. Dealing with the qualitative data you gather is as time-consuming - at least until we release the Formbricks HQ 😉
<Callout title="No backend needed" type="note">
In a few weeks, youll be able to use Formbricks HQ to receive and manage submissions from any pre-existing
form. Until then, you can use Formspree.
</Callout>
## Formspree
The closest solution to Formbricks HQ is Formspree. Formspree has a rather limited free plan, but it should be enough to get you started. Once Formbricks HQ is live, youll be able to switch within minutes.
### 1. Setup Formspree account & create form
To setup Formspree, go over to [formspree.io](https://formspree.io), create an account and create a form:
<Image src={Image1} alt="Formspree open source alternative for free step 1" className="rounded-lg" />
### 2. Copy endpoint URL
Copy endpoint URL out of Formspree dashboard:
<Image
src={Image2}
alt="formspree alternative to open source for free and opensource step 2"
className="rounded-lg"
/>
### 3. Update form action
All you have to do now is to set the endpoint URL as the form action (replace ID with your form ID):
```jsx
<Form
onSubmit={({ data }) => {
fetch("https://formspree.io/f/YOUR_FORMSPREE_ID", {
method: "POST",
body: JSON.stringify(data),
headers: {
Accept: "application/json",
},
});
}}>
{/* YOUR FORM */}
</Form>
```
### 4. Test it
When youre now filling out your form, you should receive the submissions in your Formspree dashboard.
<Image src={Image3} alt="free alternative to formspree open source step 3" className="rounded-lg" />
### 5. Work with form data
Out of Formspree you can send the submissions to yourself via email (only the email youre signed up with), forward it to Zapier, etc.
**Remember**: Youre using the **free plan which includes only 50 submissions / month**, apart from quite a lot of other limitations. For more features please see the [Formspree pricing](https://formspree.io/plans).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,139 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import StyleClasses from "./html-classes-of-formbricks-react-form-library-to-custom-style-surveys-and-forms.png";
import Styled from "./simple-styling-for-best-react-from-builder-library-to-make-open-source-surveys-and-forms.png";
export const meta = {
title: "Styling with CSS - Formbricks React Form Library",
};
Giving your form the right look and feel is very likely why you chose to use code. Formbricks React supports styling with a custom style sheet as well as Tailwind CSS.
### Creating custom style sheet
1. Create a new `style.css` file in your project folder.
2. Import it into your form component (e.g. `Form.jsx`)
```jsx
import style from "./style.css";
```
3. Add styles to it. You can copy this template as a quick start
```css
.formbricks-form {
background-color: #e2e8f0;
padding: 1em;
margin: 2em;
border-radius: 0.3em;
display: inline-block;
}
.formbricks-form .formbricks-outer:not(:first-child) {
margin-top: 1em;
}
.formbricks-help {
font-size: 0.8em;
}
.formbricks-wrapper {
padding-top: 2px;
}
.formbricks-label {
font-size: 0.9em;
font-weight: bold;
margin-bottom: 12px;
}
.formbricks-inner {
margin-top: 6px;
}
.formbricks-input {
border-radius: 6px;
color: black;
border: 0px;
padding: 8px;
font-size: 1em;
font-family: Arial, Helvetica, sans-serif;
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
```
When you copied the style above to your styles.css you form should look like this now:
<Image
src={Styled}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
## How does it work?
Each form element component follows the same naming convention. This means that you can style e.g. all input fields at the same time. These are the classes each form has:
<Image
src={StyleClasses}
alt="Data log of a form created with the fastest react form builder"
className="rounded-lg"
/>
| CSS Class | Description |
| ------------------- | ------------------------------------------------------------------------------------------ |
| formbricks-form | The outermost wrapping element. |
| formbricks-outer | A wrapper around the label input, help text and error messages. |
| formbricks-help | The help text itself. |
| formbricks-wrapper | A wrapper around the label and the input field (no help text). |
| formbricks-label | The label itself. |
| formbricks-inner | A wrapper around the input element. |
| formbricks-input | The input element itself. |
| formbricks-message | The element (or many elements) containing a message — often validation and error messages. |
| formbricks-messages | A wrapper around all the messages. |
### In React app, a simple form with one field looks like this:
```jsx
<Form onSubmit={() => {}>
<Text name="firstname" label="What's your first name?" validation="required" />
<Submit name="submit" label="Submit" />
</Form>
```
In your browser, it is interpreted as follows:
```html
<form class="formbricks-form">
<!-- Text input component -->
<div class="formbricks-outer" data-type="text">
<div class="formbricks-wrapper">
<label class="formbricks-label" for="firstname-JCc">What's your first name?</label>
<div class="formbricks-inner">
<input class="formbricks-input"
type="text"
id="firstname=JCc"
placeholder=""
name="firstname" />
</div>
</div>
</div>
<!-- Submit Button Component -->
</div>
<div class="formbricks-outer" data-type="submit">
<div class="formbricks-wrapper">
<button class="formbricks-input" type="submit" id="submit-tDy">
Submit
</button>
</div>
</div>
</form>
```
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,34 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
export const meta = {
title: "Tailwind CSS - Formbricks React Form Library",
};
We love Tailwind! This is why Formbricks React natively supports Tailwind. All you have to do is target the classes using props. For example, to extend “formbricks-outer” class:
```jsx
<Text name="firstname" label="What's your first name?" outerClassName="bg-slate-800 my-5" />
```
### Overview of props to target CSS classes
Here are all the props you can use to extend the styling of the different form elements:
| CSS class | Prop | Content |
| ------------------- | ----------------- | ------------------------------------------------------------ |
| formbricks-form | formClassName | The wrapper around the complete form |
| formbricks-outer | outerClassName | The wrapper around label, input field and help text |
| formbricks-legend | legendClassName | The label of the options group (only radio & checkbox input) |
| formbricks-help | helpClassName | The help text |
| formbricks-options | optionsClassName | A wrapper around all options (only radio & checkbox input) |
| formbricks-option | optionClassName | A wrapper around each option (only radio & checkbox input) |
| formbricks-wrapper | wrapperClassName | The wrapper around the label and the input field |
| formbricks-label | labelClassName | The label |
| formbricks-inner | innerClassName | The input field |
| formbricks-input | inputClassName | The input |
| formbricks-message | messageClassName | The validation / error message itself |
| formbricks-messages | messagesClassName | Wrapper around all error messages |
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

View File

@@ -1,77 +0,0 @@
import { Layout } from "@/components/docs/Layout";
import { Callout } from "@/components/shared/Callout";
import Image from "next/image";
import ErrorMsgImg from "./validation-errors-form-react-library-open-source-best-way-to-build-forms-react.png";
import Styling from "./styling-of-validation-errors-form-react-library-open-source-best-and-fastest-way-to-build-forms-react.png";
export const meta = {
title: "Validation & Error Message - Formbricks React Form Library",
};
Validation prevents users from submitting missing of false data.
To add a validation to your inputs, add the `validation` prop and write the rules in string syntax. Rules are divided by a pipe (`|`), e.g.:
```jsx
<Text name="age" label="What's your age?" validation="required|number|min:0|max:100" />
```
The code above checks four characteristics:
- The field is required, so is there a value?
- Is the value a `number`?
- Is the value positive?
- Is the value less or equal to 100?
Only if all four requirements are met, the form can be submitted. If not an error message is shown.
### Available rules
| Rule | Explanation | Example |
| ------------ | ------------------------------------------------------------------------------------------- | ---------- |
| **accepted** | Only accepts `true`, `1`, `"on"`, and `"yes"` as values (useful e.g. for single checkboxes) | "accepted" |
| **email** | Only accepts valid email address format | "email" |
| **min** | Only accepts number values that are greater or equal to the value provided | "min:10" |
| **max** | Only accepts number values that are greater or equal to the value provided | "max:50" |
| **number** | Only accepts fields with a number or float value | "number" |
| **required** | Only accepts non-empty fields | "required" |
| **url** | Only accepts valid url format (including protocol) | "url" |
### Message position
If one validation rule fails it will throw an error message. The error messages are displayed below the input field as soon as the input changes to an invalid value.
<Image
src={ErrorMsgImg}
alt="Illustration of error message and validation handling in best form react lib"
className="rounded-lg"
/>
### Message styling with CSS
You can style it as you like with CSS and Tailwind. For a custom style sheet, use the classes
`formbricks-message` and `formbricks-messages`
to style the message wrapper and the message itself:
<Image
src={Styling}
alt="Illustration of error message and validation handling in best form react lib"
className="rounded-lg"
/>
### Message styling with Tailwind
```jsx
<Text
name="email"
label="Email"
messagesClassName="bg-slate-100 rounded"
messageClassName="text-base sm:text-sm text-red-500"
/>
```
Here are the in-depth guides for [CSS](/docs/react-form-library/style-css) or [Tailwind](/docs/react-form-library/style-tailwind).
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;

Some files were not shown because too many files have changed in this diff Show More