- )
-}
diff --git a/apps/formbricks-com/app/docs/actions/code/page.mdx b/apps/formbricks-com/app/docs/actions/code/page.mdx
new file mode 100644
index 0000000000..067d451f73
--- /dev/null
+++ b/apps/formbricks-com/app/docs/actions/code/page.mdx
@@ -0,0 +1,25 @@
+export const meta = {
+ title: "Code Actions",
+ description:
+ "Integrate code actions in Formbricks using formbricks.track() to trigger surveys based on user actions, like button clicks, for precise insights. All open-source.",
+};
+
+[Actions]()
+
+# Code Actions
+
+Actions can also be set in the code base. You can fire an action using `formbricks.track()`
+
+```javascript
+formbricks.track("Action Name");
+```
+
+Here is an example of how to fire an action when a user clicks a button:
+
+```javascript
+const handleClick = () => {
+ formbricks.track("Button Clicked");
+};
+
+return ;
+```
diff --git a/apps/formbricks-com/app/docs/actions/no-code/page.mdx b/apps/formbricks-com/app/docs/actions/no-code/page.mdx
new file mode 100644
index 0000000000..49e728e302
--- /dev/null
+++ b/apps/formbricks-com/app/docs/actions/no-code/page.mdx
@@ -0,0 +1,30 @@
+export const meta = {
+ title: "No-Code Actions",
+ description:
+ "Utilize Formbricks' No-Code Actions like Page URL, innerText, and CSS Selector for easy survey triggers and enhanced user insights.",
+};
+
+[Actions]()
+
+# No-Code Actions
+
+No-Code actions can be set up within Formbricks with just a few clicks. There are three types of No-Code actions:
+
+## Page URL Action
+
+The page URL action is triggered, when a user visits a specific page in your application. There are several match conditions:
+
+- `exactMatch`: The URL should exactly match the provided string.
+- `contains`: The URL should contain the specified string as a substring.
+- `startsWith`: The URL should start with the specified string.
+- `endsWith`: The URL should end with the specified string.
+- `notMatch`: The URL should not match the specified condition.
+- `notContains`: The URL should not contain the specified string as a substring.
+
+## innerText Action
+
+The innerText action checks if the `innerText` of a clicked HTML element matches a specific text, e.g. the label of a button. Display a survey on any button click!
+
+## CSS Selector Action
+
+The CSS Selector action checks if the provided CSS selector matches the selector of a clicked HTML element. The CSS selector can be a class, id or any other CSS selector within your website. Display a survey on any element click!
diff --git a/apps/formbricks-com/app/docs/actions/why/page.mdx b/apps/formbricks-com/app/docs/actions/why/page.mdx
new file mode 100644
index 0000000000..6b0d102a64
--- /dev/null
+++ b/apps/formbricks-com/app/docs/actions/why/page.mdx
@@ -0,0 +1,23 @@
+export const meta = {
+ title: "What are actions and why are they useful?",
+ description:
+ "Actions in Formbricks enable targeted survey displays during specific user journey moments. Enhance user segmentation by tracking actions for granular surveying.",
+};
+
+[Actions]()
+
+# What are actions and why are they useful?
+
+You want to understand what your users think and feel during specific moments in the user journey. To be able to ask at exactly the right point in time, you need actions.
+
+## What are actions?
+
+Actions are a little notification sent from your application to Formbricks. You decide which actions are sent either in your [Code](/docs/actions/code) or by setting up a [No-Code](/docs/actions/no-code) action within Formbricks.
+
+## How do actions work?
+
+When a predefined action happens in your app, the Formbricks widget notices. This action can then trigger a survey to be shown to the user and is stored in the database.
+
+## Why are actions useful?
+
+Actions help you to display your surveys at the right time. Later on, you will be able to segment your users based on the actions they have triggered in the past. This way, you can create much more granular user segments, e.g. only target users that already have used a specific feature.
diff --git a/apps/formbricks-com/app/docs/api/api-key-setup/add-api-key.png b/apps/formbricks-com/app/docs/api/api-key-setup/add-api-key.png
new file mode 100644
index 0000000000..8ea4a144a1
Binary files /dev/null and b/apps/formbricks-com/app/docs/api/api-key-setup/add-api-key.png differ
diff --git a/apps/formbricks-com/app/docs/api/api-key-setup/api-key-secret.png b/apps/formbricks-com/app/docs/api/api-key-setup/api-key-secret.png
new file mode 100644
index 0000000000..c30d79529a
Binary files /dev/null and b/apps/formbricks-com/app/docs/api/api-key-setup/api-key-secret.png differ
diff --git a/apps/formbricks-com/app/docs/api/api-key-setup/page.mdx b/apps/formbricks-com/app/docs/api/api-key-setup/page.mdx
new file mode 100644
index 0000000000..9a03843f62
--- /dev/null
+++ b/apps/formbricks-com/app/docs/api/api-key-setup/page.mdx
@@ -0,0 +1,40 @@
+import Image from "next/image";
+
+import AddApiKey from "./add-api-key.png";
+import ApiKeySecret from "./api-key-secret.png";
+
+export const meta = {
+ title: "API Key Setup",
+ description:
+ "Generate, store, and delete personal API keys for secure Formbricks access. Ensure safekeeping to prevent unauthorized account control.",
+};
+
+[API]()
+
+# API Key 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 settings on [app.formbricks.com](https://app.formbricks.com).
+2. Go to page “API keys”
+
+3. Create a key for the development or production environment.
+4. Copy the key immediately. You won’t be able to see it again.
+
+
+
+ ## Store API key safely {{ class: "text-white" }}
+ Anyone who has your API key has full control over your account. For security reasons, you cannot view the API
+ key again.
+
+
+### Delete a personal API key
+
+1. Go to settings on [app.formbricks.com](https://app.formbricks.com/).
+2. Go to page “API keys”.
+3. Find the key you wish to revoke and select “Delete”.
+4. Your API key will stop working immediately.
diff --git a/apps/formbricks-com/app/docs/api/get-responses/page.mdx b/apps/formbricks-com/app/docs/api/get-responses/page.mdx
new file mode 100644
index 0000000000..a462b39040
--- /dev/null
+++ b/apps/formbricks-com/app/docs/api/get-responses/page.mdx
@@ -0,0 +1,104 @@
+export const meta = {
+ title: "API: Get Responses",
+ description: "Fetch all the responses for your environment.",
+};
+
+[API]()
+
+# API: Get Responses
+
+## List all Responses {{ tag: 'GET', label: '/api/v1/responses' }}
+
+
+
+
+ Retrieve all the responses you have received for all your surveys.
+
+ ### Mandatory Headers
+
+
+
+ Your Formbricks API key.
+
+
+
+ ### Optional Query Params
+
+
+ SurveyId to filter responses by.
+
+
+
+
+
+
+
+
+ ```bash {{ title: 'cURL' }}
+ curl --location \
+ 'https://app.formbricks.com/api/v1/responses' \
+ --header \
+ 'x-api-key: '
+ ```
+
+
+
+
+
+ ```json {{title:'200 Success'}}
+ {
+ "data":[
+ {
+ "id":"cllnfybxd051rpl0gieavthr9",
+ "createdAt":"2023-08-23T07:56:33.121Z",
+ "updatedAt":"2023-08-23T07:56:41.793Z",
+ "surveyId":"cllnfy2780fromy0hy7uoxvtn",
+ "finished":true,
+ "data":{
+ "ec7agikkr58j8uonhioinkyk":"Loved it!",
+ "gml6mgy71efgtq8np3s9je5p":"clicked",
+ "klvpwd4x08x8quesihvw5l92":"Product Manager",
+ "kp62fbqe8cfzmvy8qwpr81b2":"Very disappointed",
+ "lkjaxb73ulydzeumhd51sx9g":"Not interesed.",
+ "ryo75306flyg72iaeditbv51":"Would love if it had dark theme."
+ },
+ "meta":{
+ "url":"https://app.formbricks.com/s/cllnfy2780fromy0hy7uoxvtn",
+ "userAgent":{
+ "os":"Linux",
+ "browser":"Chrome"
+ }
+ },
+ "personAttributes":null,
+ "person":null,
+ "notes":[],
+ "tags":[]
+ }
+ ]
+ }
+ ```
+
+ ```json {{ title: '404 Not Found' }}
+ {
+ "code": "not_found",
+ "message": "cllnfy2780fromy0hy7uoxvt not found",
+ "details": {
+ "resource_id": "survey",
+ "resource_type": "cllnfy2780fromy0hy7uoxvt"
+ }
+ }
+ ```
+
+ ```json {{ title: '401 Not Authenticated' }}
+ {
+ "code": "not_authenticated",
+ "message": "Not authenticated",
+ "details": {
+ "x-Api-Key": "Header not provided or API Key invalid"
+ }
+ }
+ ```
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/api/overview/page.mdx b/apps/formbricks-com/app/docs/api/overview/page.mdx
new file mode 100644
index 0000000000..2aad095ddb
--- /dev/null
+++ b/apps/formbricks-com/app/docs/api/overview/page.mdx
@@ -0,0 +1,27 @@
+export const meta = {
+ title: "API Overview",
+ description:
+ "Explore Formbricks' APIs: Public Client API for client-side tasks, and User API for account management with secure API Key authentication.",
+};
+
+[API]()
+
+# API Overview
+
+Formbricks offers two types of APIs: the Public Client API and the User API. Each API serves a different purpose, has different authentication requirements, and provides access to different data and settings.
+
+## Public Client API
+
+The Public Client API is designed for the JavaScript SDK and does not require authentication. It's primarily used for creating persons, sessions, and responses within the Formbricks platform. This API is ideal for client-side interactions, as it doesn't expose sensitive information.
+
+## User API
+
+The User API provides access to all data and settings that are visible in the Formbricks App. This API requires a personal API Key for authentication, which can be generated in the Settings section of the Formbricks App. With the User API, you can manage your Formbricks account programmatically, accessing and modifying data and settings as needed.
+
+**Auth:** Personal API Key
+
+API requests made to the User API are authorized using a personal API key. This key grants the same rights and access as if you were logged in at formbricks.com. It's essential to keep your API key secure and not share it with others.
+
+To generate, store, or delete an API key, follow the instructions provided on the following page [API Key](/docs/api/api-key-setup).
+
+By understanding the differences between these two APIs, you can choose the appropriate one for your needs, ensuring a secure and efficient integration with the Formbricks platform.
diff --git a/apps/formbricks-com/app/docs/attachments/page.mdx b/apps/formbricks-com/app/docs/attachments/page.mdx
deleted file mode 100644
index cd36364d74..0000000000
--- a/apps/formbricks-com/app/docs/attachments/page.mdx
+++ /dev/null
@@ -1,363 +0,0 @@
-export const metadata = {
- title: 'Attachments',
- description:
- 'On this page, we’ll dive into the different attachment endpoints you can use to manage attachments programmatically.',
-}
-
-# Attachments
-
-Attachments are how you share things in Protocol — they allow you to send all sorts of files to your contacts and groups. On this page, we'll dive into the different attachment endpoints you can use to manage attachments programmatically. We'll look at how to query, upload, update, and delete attachments. {{ className: 'lead' }}
-
-## The attachment model
-
-The attachment model contains all the information about the files you send to your contacts and groups, including the name, type, and size.
-
-### Properties
-
-
-
- Unique identifier for the attachment.
-
-
- Unique identifier for the message associated with the attachment.
-
-
- The filename for the attachment.
-
-
- The URL for the attached file.
-
-
- The MIME type of the attached file.
-
-
- The file size of the attachment in bytes.
-
-
- Timestamp of when the attachment was created.
-
-
-
----
-
-## List all attachments {{ tag: 'GET', label: '/v1/attachments' }}
-
-
-
-
- This endpoint allows you to retrieve a paginated list of all your attachments (in a conversation if a conversation id is provided). By default, a maximum of ten attachments are shown per page.
-
- ### Optional attributes
-
-
-
- Limit to attachments from a given conversation.
-
-
- Limit the number of attachments returned.
-
-
-
-
-
-
- This endpoint allows you to upload a new attachment to a conversation. See the code examples for how to send the file to the Protocol API.
-
- ### Required attributes
-
-
-
- The file you want to add as an attachment.
-
-
-
-
-
-
- This endpoint allows you to retrieve an attachment by providing the attachment id. Refer to [the list](#the-attachment-model) at the top of this page to see which properties are included with attachment objects.
-
-
-
-
- This endpoint allows you to perform an update on an attachment. Currently, the only supported type of update is changing the filename.
-
- ### Optional attributes
-
-
-
- The new filename for the attachment.
-
-
-
-
-
-
- This endpoint allows you to delete attachments. Note: This will permanently delete the file.
-
-
-
-
-
-
- ```bash {{ title: 'cURL' }}
- curl -X DELETE https://api.protocol.chat/v1/attachments/Nc6yKKMpcxiiFxp6 \
- -H "Authorization: Bearer {token}"
- ```
-
- ```js
- import ApiClient from '@example/protocol-api'
-
- const client = new ApiClient(token)
-
- await client.attachments.delete('Nc6yKKMpcxiiFxp6')
- ```
-
- ```python
- from protocol_api import ApiClient
-
- client = ApiClient(token)
-
- client.attachments.delete("Nc6yKKMpcxiiFxp6")
- ```
-
- ```php
- $client = new \Protocol\ApiClient($token);
-
- $client->attachments->delete('Nc6yKKMpcxiiFxp6');
- ```
-
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/attributes/custom-attributes/page.mdx b/apps/formbricks-com/app/docs/attributes/custom-attributes/page.mdx
new file mode 100644
index 0000000000..1e39033fe2
--- /dev/null
+++ b/apps/formbricks-com/app/docs/attributes/custom-attributes/page.mdx
@@ -0,0 +1,27 @@
+export const meta = {
+ title: "Setting attributes with code",
+ description:
+ "Set attributes in code using setAttribute function. Enhance user segmentation, target surveys effectively, and gather valuable insights for better decisions. All open-source.",
+};
+
+[Attributes]()
+
+# Setting attributes with code
+
+One way to send attributes to Formbricks is in your code. In Formbricks, there are two special attributes for [user identification](/docs/attributes/identify-users)(user ID & email) and custom attributes. An example:
+
+### Setting Custom User Attributes
+
+You can use the setAttribute function to set any custom attribute for the user (e.g. name, plan, etc.):
+
+```javascript
+formbricks.setAttribute("Plan", "Pro");
+```
+
+Generally speaking, the setAttribute function works like this:
+
+```javascript
+formbricks.setAttribute("attribute_key", "attribute_value");
+```
+
+Where `attributeName` is the name of the attribute you want to set, and `attributeValue` is the value of the attribute you want to set.
diff --git a/apps/formbricks-com/app/docs/attributes/identify-users/page.mdx b/apps/formbricks-com/app/docs/attributes/identify-users/page.mdx
new file mode 100644
index 0000000000..42cd5a0dec
--- /dev/null
+++ b/apps/formbricks-com/app/docs/attributes/identify-users/page.mdx
@@ -0,0 +1,45 @@
+export const meta = {
+ title: "Identifying Users",
+ description:
+ "Identify users with Formbricks by setting User ID, email, and custom attributes. Enhance survey targeting and recontacting while maintaining user privacy.",
+};
+
+[Attributes]()
+
+# Identifying Users
+
+At Formbricks, we value user privacy. By default, Formbricks doesn't collect or store any personal information from your users. However, we understand that it can be helpful for you to know which user submitted the feedback and also functionality like recontacting users and controlling the waiting period between surveys requires identifying the users. That's why we provide a way for you to share existing user data from your app, so you can view it in our dashboard.
+
+Once the Formbricks widget is loaded on your web app, our SDK exposes methods for identifying user attributes. Let's set it up!
+
+## Setting User ID
+
+You can use the `setUserId` function to identify a user with any string. It's best to use the default identifier you use in your app (e.g. unique id from database) but you can also anonymize these as long as they are unique for every user. This function can be called multiple times with the same value safely and stores the identifier in local storage. We recommend you set the User ID whenever the user logs in to your website, as well as after the installation snippet (if the user is already logged in).
+
+```javascript
+formbricks.setUserId("USER_ID");
+```
+
+## Setting User Email
+
+You can use the setEmail function to set the user's email:
+
+```javascript
+formbricks.setEmail("user@example.com");
+```
+
+### Setting Custom User Attributes
+
+You can use the setAttribute function to set any custom attribute for the user (e.g. name, plan, etc.):
+
+```javascript
+formbricks.setAttribute("attribute_key", "attribute_value");
+```
+
+### Logging Out Users
+
+When a user logs out of your webpage, make sure to log them out of Formbricks as well. This will prevent new activity from being associated with an incorrect user. Use the logout function:
+
+```javascript
+formbricks.logout();
+```
diff --git a/apps/formbricks-com/app/docs/attributes/why/page.mdx b/apps/formbricks-com/app/docs/attributes/why/page.mdx
new file mode 100644
index 0000000000..d635ba0ecb
--- /dev/null
+++ b/apps/formbricks-com/app/docs/attributes/why/page.mdx
@@ -0,0 +1,23 @@
+export const meta = {
+ title: "What are attributes and why are they useful?",
+ description:
+ "How to use attributes for user segmentation, enhancing survey targeting & results. Improve feedback quality and make data-driven decisions.",
+};
+
+[Attributes]()
+
+# What are attributes and why are they useful?
+
+Surveying your user base without segmentation leads to weak results and survey fatigue. Attributes help you segment your users into groups.
+
+## What are attributes?
+
+Attributes are key-value pairs that you can set for each person individually. For example, the attribute "Plan" can be set to "Free" or "Paid".
+
+## How do attributes work?
+
+Attributes are sent from your application to Formbricks and are associated with the current user. We store it in our database and allow you to use it the next time you create a survey.
+
+## Why are attributes useful?
+
+Attributes help show surveys to the right group of people. For example, you can show a survey to all users who have a "Plan" attribute set to "Paid".
diff --git a/apps/formbricks-com/app/docs/authentication/page.mdx b/apps/formbricks-com/app/docs/authentication/page.mdx
deleted file mode 100644
index e9e2f8e0f7..0000000000
--- a/apps/formbricks-com/app/docs/authentication/page.mdx
+++ /dev/null
@@ -1,44 +0,0 @@
-export const metadata = {
- title: 'Authentication',
- description:
- 'In this guide, we’ll look at how authentication works. Protocol offers two ways to authenticate your API requests: Basic authentication and OAuth2 with a token.',
-}
-
-# Authentication
-
-You'll need to authenticate your requests to access any of the endpoints in the Protocol API. In this guide, we'll look at how authentication works. Protocol offers two ways to authenticate your API requests: Basic authentication and OAuth2 with a token — OAuth2 is the recommended way. {{ className: 'lead' }}
-
-## Basic authentication
-
-With basic authentication, you use your username and password to authenticate your HTTP requests. Unless you have a very good reason, you probably shouldn't use basic auth. Here's how to authenticate using cURL:
-
-```bash {{ title: 'Example request with basic auth' }}
-curl https://api.protocol.chat/v1/conversations \
- -u username:password
-```
-
-Please don't commit your Protocol password to GitHub!
-
-## OAuth2 with bearer token
-
-The recommended way to authenticate with the Protocol API is by using OAuth2. When establishing a connection using OAuth2, you will need your access token — you will find it in the [Protocol dashboard](#) under API settings. Here's how to add the token to the request header using cURL:
-
-```bash {{ title: 'Example request with bearer token' }}
-curl https://api.protocol.chat/v1/conversations \
- -H "Authorization: Bearer {token}"
-```
-
-Always keep your token safe and reset it if you suspect it has been compromised.
-
-## Using an SDK
-
-If you use one of our official SDKs, you won't have to worry about any of the above — fetch your access token from the [Protocol dashboard](#) under API settings, and the client library will take care of the rest. All the client libraries use OAuth2 behind the scenes.
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/change-text.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/change-text.png
new file mode 100644
index 0000000000..1908b5f5be
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/change-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/create-cancel-flow.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/create-cancel-flow.png
new file mode 100644
index 0000000000..7526a42b9a
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/create-cancel-flow.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/page.mdx b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/page.mdx
new file mode 100644
index 0000000000..416822080d
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/page.mdx
@@ -0,0 +1,126 @@
+import Image from "next/image";
+import DemoPreview from "@/components/dummyUI/DemoPreview";
+
+import CreateChurnFlow from "./create-cancel-flow.png";
+import ChangeText from "./change-text.png";
+import TriggerInnerText from "./trigger-inner-text.png";
+import TriggerCSS from "./trigger-css-selector.png";
+import TriggerPageUrl from "./trigger-page-url.png";
+import RecontactOptions from "./recontact-options.png";
+import PublishSurvey from "./publish-survey.png";
+import SelectAction from "./select-action.png";
+
+export const meta = {
+ title: "Learn from Churn",
+ description: "To know how to decrease churn, you have to understand it. Use a micro-survey.",
+};
+
+[Best Practices]()
+
+# Learn from Churn
+
+Churn is hard, but can teach you a lot. Whenever a user decides that your product isn’t worth it anymore, you have a unique opportunity to get deep insights. These insights are pure gold to reduce churn.
+
+## Purpose
+
+The Churn Survey is among the most effective ways to identify weaknesses in you offering. People were willing to pay but now are not anymore: What changed? Let’s find out!
+
+## Preview
+
+
+
+## Formbricks Approach
+
+- Ask at exactly the right point in time
+- Follow-up to prevent bad reviews
+- Coming soon: Make survey mandatory
+
+## Overview
+
+To run the Churn Survey in your app you want to proceed as follows:
+
+1. Create new Churn Survey at [app.formbricks.com](http://app.formbricks.com/)
+2. Set up the user action to display survey at right point in time
+3. Choose correct recontact options to never miss a feedback
+4. Prevent that churn!
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ We assume that you have already installed the Formbricks Widget in your web app. It’s required to display messages
+ and surveys in your app. If not, please follow the [Quick Start Guide (takes 15mins max.)](/docs/getting-started/quickstart)
+
+
+### 1. Create new Churn Survey
+
+If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
+
+Click on "Create Survey" and choose the template “Churn Survey”:
+
+
+
+### 2. Update questions (if you like)
+
+You’re free to update the question and answer options. However, based on our experience, we suggest giving the provided template a go 😊
+
+
+
+_Want to change the button color? You can do so in the product settings._
+
+Save, and move over to the “Audience” tab.
+
+### 3. Pre-segment your audience
+
+In this case, you don’t really need to pre-segment your audience. You likely want to ask everyone who hits the “Cancel subscription” button.
+
+### 4. Set up a trigger
+
+To create the trigger for your Churn Survey, you have two options to choose from:
+
+1. **Trigger by innerText:** You likely have a “Cancel Subscription” button in your app. You can setup a user Action with the according `innerText` to trigger the survey, like so:
+
+
+
+2. **Trigger by CSS Selector:** In case you have more than one button saying “Cancel Subscription” in your app and only want to display the survey when one of them is clicked, you want to be more specific. The best way to do that is to give this button the HTML `id=“cancel-subscription”` and set your user action up like so:
+
+
+
+3. **Trigger by pageURL:** Lastly, you could also display your survey on a subpage “/subscription-cancelled” where you forward users once they cancelled the trial subscription. You can then create a user Action with the type `pageURL` with the following settings:
+
+
+
+Whenever a user visits this page, matches the filter conditions above and the recontact options (below) the survey will be displayed ✅
+
+Here is our complete [Actions manual](/docs/actions/why) covering [Code](/docs/actions/code) and [No-Code](/docs/actions/no-code) Actions.
+
+
+ ## Pre-churn flow coming soon {{ class: "text-white" }}
+ We’re currently building full-screen survey pop-ups. You’ll be able to prevent users from closing the survey
+ unless they respond to it. It’s certainly debatable if you want that but you could force them to click through
+ the survey before letting them cancel 🤷
+
+
+### 5. Select Action in the “When to ask” card
+
+
+
+### 6. Last step: Set Recontact Options correctly
+
+Lastly, scroll down to “Recontact Options”. Here you have to choose the correct settings to make sure you milk these super valuable insights. You want to make sure that this survey is always displayed, no matter if the user has already seen a survey in the past days:
+
+
+
+These settings make sure the survey is always displayed, when a user wants to Cancel their subscription.
+
+### 7. Congrats! You’re ready to publish your survey 💃
+
+
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ You need to have the Formbricks Widget installed to display the Churn Survey in your app. Please follow [this
+ tutorial (Step 4 onwards)](/docs/getting-started/quickstart) to install the widget.
+
+
+###
+
+# Get those insights! 🎉
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/publish-survey.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/publish-survey.png
new file mode 100644
index 0000000000..5d21ed596f
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/publish-survey.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/recontact-options.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/recontact-options.png
new file mode 100644
index 0000000000..5995f97fdd
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/recontact-options.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/select-action.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/select-action.png
new file mode 100644
index 0000000000..94cc8eb004
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/select-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-css-selector.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-css-selector.png
new file mode 100644
index 0000000000..806170f0d3
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-css-selector.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-inner-text.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-inner-text.png
new file mode 100644
index 0000000000..103d0764fc
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-inner-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-page-url.png b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-page-url.png
new file mode 100644
index 0000000000..c66b870928
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/cancel-subscription/trigger-page-url.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/add-action.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/add-action.png
new file mode 100644
index 0000000000..7ebb5853f7
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/add-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/change-id.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/change-id.png
new file mode 100644
index 0000000000..fc83c4ef02
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/change-id.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/copy-ids.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/copy-ids.png
new file mode 100644
index 0000000000..f2e8481112
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/copy-ids.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/docs-navi.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/docs-navi.png
new file mode 100644
index 0000000000..df5b0a319f
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/docs-navi.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/docs-template.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/docs-template.png
new file mode 100644
index 0000000000..c689d8f440
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/docs-template.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/page.mdx b/apps/formbricks-com/app/docs/best-practices/docs-feedback/page.mdx
new file mode 100644
index 0000000000..f4b21a8c9e
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/docs-feedback/page.mdx
@@ -0,0 +1,386 @@
+import Image from "next/image";
+
+import DocsFeedback from "@/components/docs/DocsFeedback";
+import AddAction from "./add-action.png";
+import ChangeId from "./change-id.png";
+import DocsNavi from "./docs-navi.png";
+import DocsTemplate from "./docs-template.png";
+import SelectNonevent from "./select-nonevent.png";
+import SwitchToDev from "./switch-to-dev.png";
+import WhenToAsk from "./when-to-ask.png";
+import CopyIds from "./copy-ids.png";
+
+export const meta = {
+ title: "Docs Feedback",
+ description: "Docs Feedback allows you to measure how clear your documentation is.",
+};
+
+[Best Practices]()
+
+# Docs Feedback
+
+Docs Feedback allows you to measure how clear your documentation is.
+
+## Purpose
+
+Unlike yourself, your users don't spend 5-7 days per week thinking about your product. To fight the "Curse of Knowledge" you have to measure how clear your docs are.
+
+## Preview
+
+
+
+## Installation
+
+To get this running, you'll need a bit of time. Here are the steps we're going through:
+
+1. Set up Formbricks Cloud
+2. Build the frontend
+3. Connect to API
+4. Test
+
+### 1. Setting up Formbricks Cloud
+
+1. To get started, create an account for the [Formbricks Cloud](https://app.formbricks.com/auth/signup).
+
+2. In the Menu (top right) you see that you can switch between a “Development” and a “Production” environment. These are two separate environments so your test data doesn’t mess up the insights from prod. Switch to “Development”:
+
+
+
+3. Then, create a survey using the template “Docs Feedback”:
+
+
+
+4. Change the Internal Question ID of the first question to **“isHelpful”** to make your life easier 😉
+
+
+
+5. In the same way, you can change the Internal Question ID of the _Please elaborate_ question to **“additionalFeedback”** and the one of the _Page URL_ question to **“pageUrl”**.
+
+
+ ## Answers need to be identical {{ class: "text-white" }}
+ If you want different answers than “Yes 👍” and “No 👎” you need update the choices accordingly. They have to
+ be identical to the frontend we're building in the next step.
+
+
+6. Click on “Continue to Settings or select the audience tab manually. Scroll down to “When to ask” and create a new Action:
+
+
+
+7. Our goal is to create an event that never fires. This is a bit nonsensical because it is a workaround. Stick with me 😃 Fill the action out like on the screenshot:
+
+
+
+8. Select the Non-Event in the dropdown. Now you see that the “Publish survey” button is active. Publish your survey 🤝
+
+
+
+**You’re all setup in Formbricks Cloud for now 👍**
+
+### 2. Build the frontend
+
+
+ ## Your frontend might work differently {{ class: "text-white" }}
+ Your frontend likely looks and works differently. This is an example specific to our tech stack. We want to illustrate
+ what you should consider building yours 😊
+
+
+Before we start, lets talk about the widget. It works like this:
+
+- Once the user selects yes/no, a partial response is sent to the Formbricks API. It includes the feedback and the current page url.
+- Then the user is presented with an additional open text field to further explain their choice. Once it's submitted, the previous response is updated with the additional feedback.
+
+This allows us to capture and analyze partial feedback where the user is not willing to provide additional information.
+
+**Let's do this 👇**
+
+1. Open the code editor where you handle your docs page.
+
+2. Likely, you have a template file or similar which renders the navigation at the bottom of the page:
+
+
+
+Locate that file. We are using the [Tailwind Template “Syntax”](https://tailwindui.com/templates/syntax) for our docs. Here is our [Layout.tsx](https://github.com/formbricks/formbricks/blob/main/apps/formbricks-com/components/docs/Layout.tsx) file.
+
+3. Write the frontend code for the widget. Here is the full component (we break it down right below):
+
+```tsx
+import { useState } from "react";
+import { handleFeedbackSubmit, updateFeedback } from "../../lib/handleFeedbackSubmit";
+import { Popover, PopoverTrigger, PopoverContent, Button } from "@formbricks/ui";
+import { useRouter } from "next/router";
+
+export default function DocsFeedback() {
+ const router = useRouter();
+ const [isOpen, setIsOpen] = useState(false);
+ const [sharedFeedback, setSharedFeedback] = useState(false);
+ const [responseId, setResponseId] = useState(null);
+ const [freeText, setFreeText] = useState("");
+
+ if (
+ !process.env.NEXT_PUBLIC_FORMBRICKS_COM_DOCS_FEEDBACK_SURVEY_ID ||
+ !process.env.NEXT_PUBLIC_FORMBRICKS_COM_API_HOST ||
+ !process.env.NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID
+ ) {
+ return null;
+ }
+
+ return (
+
+ );
+}
+```
+
+**Let’s break it down!**
+
+Setting the local states and getting the current URL:
+
+```tsx
+const router = useRouter(); // to get the URL of the current docs page
+const [isOpen, setIsOpen] = useState(false); // to close Popover after
+const [sharedFeedback, setSharedFeedback] = useState(false); // to display Thank You message
+const [responseId, setResponseId] = useState(null); // to store responseID (will explain more)
+const [freeText, setFreeText] = useState(""); // to locally store the additional info provided by user
+```
+
+Disabling feedback if config environment variables are not set properly:
+
+```tsx
+// Disables feedback if key info like survey ID, API Host, or Formbricks environment ID are missing
+
+if (
+ !process.env.NEXT_PUBLIC_FORMBRICKS_COM_DOCS_FEEDBACK_SURVEY_ID ||
+ !process.env.NEXT_PUBLIC_FORMBRICKS_COM_API_HOST ||
+ !process.env.NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID
+) {
+ return null;
+}
+```
+
+The actual frontend (read comments):
+
+```tsx
+return (
+
+ {!sharedFeedback ? ( // displays Feedback buttons or Thank You message
+
+ Was this page helpful?
+
+
+ {["Yes 👍", " No 👎"].map((option) => ( // Popup Trigger is a button as well. This is a workaround to open the same form but send a different response to the API
+ {
+ const id = await handleFeedbackSubmit(option, router.asPath); // handleFeedbackSubmit sends the Yes / No choice as well as the current URL to Formbricks and returns the responseId
+ setResponseId(id); // add responseId to local state so we can use it if user decides to add more feedback in free text field
+ }}>
+ {option} // "Yes 👍" or "No 👎" - they have to be identical with the choices in the survey on app.formbricks.com for it to work (!)
+
+ ))}
+
+
+
+
+
+
+ ) : (
+
Thanks a lot, boss! 🤝
// Thank You message
+ )}
+
+ );
+}
+```
+
+## 3. Connecting to the Formbricks API
+
+The last step is to hook up your sparkling new frontend to the Formbricks API. To do so, we followed the “[Create Response](/docs/client-api/create-response)” and “[Update Response](/docs/client-api/update-response)” pages in our docs.
+
+Here is the code for the `handleFeedbackSubmit` function with comments:
+
+```tsx
+export const handleFeedbackSubmit = async (YesNo, pageUrl) => {
+ const response_data = {
+ data: {
+ isHelpful: YesNo, // the "Yes 👍" or "No 👎" response. Remember: They have to be identical with the choices in the survey on app.formbricks.com for it to work.
+ pageUrl: pageUrl, // So you know which page the user gives feedback about.
+ },
+ };
+
+ const payload = {
+ response: response_data,
+ surveyId: process.env.NEXT_PUBLIC_FORMBRICKS_COM_DOCS_FEEDBACK_SURVEY_ID, // For testing, replace this with the survey ID of your survey (more info below)
+ };
+
+ try {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_FORMBRICKS_COM_API_HOST}/api/v1/client/environments/${process.env.NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID}/responses`, // For testing, replace this with the API host and environemnt ID of your Development environment on app.formbricks.com
+ };
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(payload),
+ }
+ );
+
+ if (res.ok) {
+ const responseJson = await res.json();
+ return responseJson.id; // Returns the response ID
+ } else {
+ console.error("Error submitting form");
+ }
+ } catch (error) {
+ console.error("Error submitting form:", error);
+ }
+};
+```
+
+And this is the `updateFeedback` function with comments:
+
+```tsx
+export const updateFeedback = async (freeText, responseId) => {
+ if (!responseId) {
+ console.error("No response ID available"); // If there is not response ID, no response can be updated.
+ return;
+ }
+
+ const payload = {
+ response: {
+ data: {
+ additionalInfo: freeText,
+ },
+ finished: true, // Lets Formbricks calculate Completion Rate
+ },
+ };
+
+ try {
+ const res = await fetch(
+ `${process.env.NEXT_PUBLIC_FORMBRICKS_COM_API_HOST}/api/v1/client/environments/${process.env.NEXT_PUBLIC_FORMBRICKS_COM_ENVIRONMENT_ID}/responses/${responseId}`,
+ {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(payload),
+ }
+ );
+
+ if (!res.ok) {
+ console.error("Error updating response");
+ }
+ } catch (error) {
+ console.error("Error updating response:", error);
+ }
+};
+```
+
+That’s almost it! 🤸
+
+## 4. Setting it up for testing
+
+Before you roll it out in production, you want to test it. To do so, you need two things:
+
+1. Environment ID (1) of the development environment on app.formbricks.com
+2. Survey ID (2) of your test survey
+
+When you are on the survey detail page, you’ll find both of them in the URL:
+
+
+
+Now, you have to replace the IDs and the API host accordingly in your `handleFeedbackSubmit`:
+
+```tsx
+ const payload = {
+ response: response_data,
+ surveyId: clgwfv4a7002el50ihyuss38x, // This is an example, replace with yours
+ };
+
+ try {
+ const res = await fetch(
+ // Note that we also updated the API host to 'https://app.formbricks.com/'
+ `https:app.formbricks.com/api/v1/client/environments/clgwcwp4z000lpf0hur7uxbuv/responses`,
+ };
+```
+
+And lastly, in the `updateFeedback` function
+
+```tsx
+ try {
+ const res = await fetch(
+ // Note that we also updated the API host to 'https://app.formbricks.com/'
+ `https:app.formbricks.com/api/v1/client/environments/clgwcwp4z000lpf0hur7uxbuv/responses/${responseId}`, // Note that we also updated the API host to 'https://app.formbricks.com/'
+}
+```
+
+### You’re good to go! 🎉
+
+Something doesn’t work? Check your browser console for the error.
+
+Can’t figure it out? [Join our Discord!](https://formbricks.com/discord)
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/select-nonevent.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/select-nonevent.png
new file mode 100644
index 0000000000..1ae4b89609
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/select-nonevent.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/switch-to-dev.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/switch-to-dev.png
new file mode 100644
index 0000000000..d257edb18a
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/switch-to-dev.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/docs-feedback/when-to-ask.png b/apps/formbricks-com/app/docs/best-practices/docs-feedback/when-to-ask.png
new file mode 100644
index 0000000000..f762837a3f
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/docs-feedback/when-to-ask.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/action-css.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/action-css.png
new file mode 100644
index 0000000000..3f828569a1
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/action-css.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/action-text.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/action-text.png
new file mode 100644
index 0000000000..f33e4125de
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/action-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/change-text.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/change-text.png
new file mode 100644
index 0000000000..78f6cfcc1d
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/change-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/create-survey.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/create-survey.png
new file mode 100644
index 0000000000..2339123901
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/create-survey.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/page.mdx b/apps/formbricks-com/app/docs/best-practices/feature-chaser/page.mdx
new file mode 100644
index 0000000000..31e77b4c7e
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/feature-chaser/page.mdx
@@ -0,0 +1,106 @@
+import DemoPreview from "@/components/dummyUI/DemoPreview";
+import Image from "next/image";
+
+import ActionCSS from "./action-css.png";
+import ActionText from "./action-text.png";
+import ChangeText from "./change-text.png";
+import CreateSurvey from "./create-survey.png";
+import Publish from "./publish.png";
+import RecontactOptions from "./recontact-options.png";
+import SelectAction from "./select-action.png";
+
+export const meta = {
+ title: "Feature Chaser",
+ description: "Follow up with users who used a specific feature. Gather feedback and improve your product.",
+};
+
+[Best Practices]()
+
+# Feature Chaser
+
+Following up on specific features only makes sense with very targeted surveys. Formbricks is built for that.
+
+## Purpose
+
+Product analytics never tell you why a feature is used - and why not. Following up on specfic features with highly relevant questions is a great way to gather feedback and improve your product.
+
+## Preview
+
+
+
+## Formbricks Approach
+
+- Trigger survey at exactly the right point in the user journey
+- Never ask twice, keep your data clean
+- Prevent survey fatigue with global waiting period
+
+## Overview
+
+To run the Feature Chaser survey in your app you want to proceed as follows:
+
+1. Create new Feature Chaser survey at [app.formbricks.com](http://app.formbricks.com/)
+2. Setup a user action to display survey at the right point in time
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ We assume that you have already installed the Formbricks Widget in your web app. It’s required to display messages
+ and surveys in your app. If not, please follow the [Quick Start Guide (takes 15mins max.)](/docs/getting-started/quickstart)
+
+
+### 1. Create new Feature Chaser
+
+If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
+
+Click on "Create Survey" and choose the template “Feature Chaser”:
+
+
+
+### 2. Update questions
+
+The questions you want to ask are dependent on your feature and can be very specific. In the template, we suggest a high-level check on how easy it was for the user to achieve their goal. We also add an opportunity to provide context:
+
+
+
+Save, and move over to where the magic happens: The “Audience” tab.
+
+### 3. Set up a trigger for the Feature Chaser survey:
+
+Before setting the right trigger, you need to identify a user action in your app which signals, that they have just used the feature you want to understand better. In most cases, it is clicking a specific button in your product.
+
+You can create [Code Actions](/docs/actions/code) and [No Code Actions](/docs/actions/no-code) to follow users through your app. In this example, we will create a No Code Action.
+
+There are two ways to track a button:
+
+1. **Trigger by innerText:** You might have a button with a unique text at the end of your feature e.g. "Export Report". You can setup a user Action with the according `innerText` to trigger the survey, like so:
+
+
+
+2. **Trigger by CSS Selector:** In case you have more than one button saying “Export Report” in your app and only want to display the survey when one of them is clicked, you want to be more specific. The best way to do that is to give this button the HTML `id=“export-report-featurename”` and set your user action up like so:
+
+
+
+Please follow our [Actions manual](/docs/actions/why) for an in-depth description of how Actions work.
+
+### 4. Select Action in the “When to ask” card
+
+
+
+### 5. Last step: Set Recontact Options correctly
+
+Lastly, scroll down to “Recontact Options”. Here you have full freedom to decide who you want to ask. Generally, you only want to ask every user once and prevent survey fatigue. It's up to you to decide if you want to ask again, when the user did not yet reply:
+
+
+
+### 7. Congrats! You’re ready to publish your survey 💃
+
+
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ You need to have the Formbricks Widget installed to display the Feature Chaser in your app. Please follow [this
+ tutorial (Step 4 onwards)](/docs/getting-started/quickstart) to install the widget.
+
+
+###
+
+# Get those insights! 🎉
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/publish.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/publish.png
new file mode 100644
index 0000000000..9cc54803e7
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/publish.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/recontact-options.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/recontact-options.png
new file mode 100644
index 0000000000..d5c8d1bd1d
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/recontact-options.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feature-chaser/select-action.png b/apps/formbricks-com/app/docs/best-practices/feature-chaser/select-action.png
new file mode 100644
index 0000000000..acc19a906e
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feature-chaser/select-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/add-action.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/add-action.png
new file mode 100644
index 0000000000..46f0bcf373
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/add-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/add-css-action.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/add-css-action.png
new file mode 100644
index 0000000000..9bbd777d0b
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/add-css-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/add-html-action.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/add-html-action.png
new file mode 100644
index 0000000000..c0882b9398
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/add-html-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/change-text-content.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/change-text-content.png
new file mode 100644
index 0000000000..432f3e4b50
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/change-text-content.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/create-feedback-box-by-template.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/create-feedback-box-by-template.png
new file mode 100644
index 0000000000..4d191b78a2
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/create-feedback-box-by-template.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/page.mdx b/apps/formbricks-com/app/docs/best-practices/feedback-box/page.mdx
new file mode 100644
index 0000000000..154b051be9
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/feedback-box/page.mdx
@@ -0,0 +1,106 @@
+import Link from "next/link";
+import Image from "next/image";
+import DemoPreview from "@/components/dummyUI/DemoPreview";
+
+import AddAction from "./add-action.png";
+import AddCSSAction from "./add-css-action.png";
+import AddHTMLAction from "./add-html-action.png";
+import ChangeTextContent from "./change-text-content.png";
+import CreateFeedbackBox from "./create-feedback-box-by-template.png";
+import PublishSurvey from "./publish-survey.png";
+import SelectAction from "./select-feedback-button-action.png";
+import RecontactOptions from "./set-recontact-options.png";
+
+export const meta = {
+ title: "Feedback Box",
+ description: "The Feedback Box gives your users a direct channel to share their feedback and feel heard.",
+};
+
+[Best Practices]()
+
+# Feedback Box
+
+The Feedback Box gives your users a direct channel to share their feedback and feel heard.
+
+## Purpose
+
+A low friction way to gather feedback helps catching even the smallest points of frustration in user experiences. Use automations to react rapidly and make users feel heard.
+
+## Preview
+
+
+
+## Formbricks Approach
+
+- Make it easy: 2 clicks to share feedback
+- Pipe insights where team can see them and react quickly
+
+## Installation
+
+To add the Feedback Box to your app, you need to perform these steps:
+
+1. Create new Feedback Box at app.formbricks.com
+2. Add user action to trigger Feedback Box
+3. Update recontact settings to display correctly
+
+### 1. Create new Feedback Box
+
+If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
+
+Then, create a new survey and look for the "Feedback Box" template:
+
+
+
+### 2. Update question content
+
+Change the questions and answer options according to your preference:
+
+
+
+### 3. Create user action to trigger Feedback Box:
+
+Go to the “Audience” tab, find the “When to send” card and choose “Add Action”. We will now use our super cool No-Code User Action Tracker:
+
+
+
+
+ ## You can also add actions in your code {{ class: "text-white" }}
+ You can also create [Code Actions](/docs/actions/code) using `formbricks.track("Eventname")` - they will automatically
+ appear in your Actions overview as long as the SDK is embedded.
+
+
+We have two options to track the Feedback Button in your application: innerText and CSS-Selector:
+
+1. **innerText:** This means that whenever a user clicks any HTML item in your app which has an `innerText` of `Feedback` the Feedback Box will be displayed.
+2. **CSS-Selector:** This means that when an element with a specific CSS-Selector like `#feedback-button` is clicked, your Feedback Box is triggered.
+
+
+
+
+
+
+### 4. Select action in the “When to ask” card
+
+
+
+### 5. Set Recontact Options correctly
+
+Scroll down to “Recontact Options”. Here you have to choose the right settings so that the Feedback Box pops up every time the user action is performed. (Our default is that every user sees every survey only once):
+
+
+
+### 6. You’re ready publish your survey!
+
+
+
+## Setting up the Widget
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ You need to have the Formbricks Widget installed to display the Feedback Box in your app. Please follow [this
+ tutorial (Step 4 onwards)](/docs/getting-started/quickstart) to install the widget.
+
+
+###
+
+# That’s it! 🎉
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/publish-survey.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/publish-survey.png
new file mode 100644
index 0000000000..87123d2a2f
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/publish-survey.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/select-feedback-button-action.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/select-feedback-button-action.png
new file mode 100644
index 0000000000..2aaa423fb9
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/select-feedback-button-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/feedback-box/set-recontact-options.png b/apps/formbricks-com/app/docs/best-practices/feedback-box/set-recontact-options.png
new file mode 100644
index 0000000000..d8a7ff132a
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/feedback-box/set-recontact-options.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/action-innertext.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/action-innertext.png
new file mode 100644
index 0000000000..8699e8f385
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/action-innertext.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/action-pageurl.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/action-pageurl.png
new file mode 100644
index 0000000000..cd5caf14e4
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/action-pageurl.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/change-text.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/change-text.png
new file mode 100644
index 0000000000..2febaed9cc
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/change-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/create-survey.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/create-survey.png
new file mode 100644
index 0000000000..1cfb3c44db
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/create-survey.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/page.mdx b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/page.mdx
new file mode 100644
index 0000000000..2258ae3fa4
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/page.mdx
@@ -0,0 +1,115 @@
+import DemoPreview from "@/components/dummyUI/DemoPreview";
+import Image from "next/image";
+
+import ActionText from "./action-innertext.png";
+import ActionPageurl from "./action-pageurl.png";
+import ChangeText from "./change-text.png";
+import CreateSurvey from "./create-survey.png";
+import Publish from "./publish.png";
+import RecontactOptions from "./recontact-options.png";
+import SelectAction from "./select-action.png";
+
+export const meta = {
+ title: "Improve Trial Conversion",
+ description: "Understand how to improve the trial conversions to get more paying customers.",
+};
+
+[Best Practices]()
+
+# Improve Trial Conversion
+
+When a user doesn't convert, you want to know why. A micro-survey displayed at exactly the right time gives you a window into understanding the most relevant question: To pay or not to pay?
+
+## Purpose
+
+The better you understand why free users don’t convert to paid users, the higher your revenue. You can make an informed decision about what to change in your offering to make more people pay for your service.
+
+## Preview
+
+
+
+## Formbricks Approach
+
+- Ask at exactly the right point in time
+- Ask to understand the problem, don’t ask for solutions
+
+## Installation
+
+To display the Trial Conversion Survey in your app you want to proceed as follows:
+
+1. Create new Trial Conversion Survey at [app.formbricks.com](http://app.formbricks.com/)
+2. Set up the user action to display survey at right point in time
+3. Print that 💸
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ We assume that you have already installed the Formbricks Widget in your web app. It’s required to display messages
+ and surveys in your app. If not, please follow the [Quick Start Guide (takes 15mins max.)](/docs/getting-started/quickstart)
+
+
+### 1. Create new Trial Conversion Survey
+
+If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
+
+Click on "Create Survey" and choose the template “Improve Trial Conversion”:
+
+
+
+### 2. Update questions (if you like)
+
+You’re free to update the questions and answer options. However, based on our experience, we suggest giving the provided template a go 😊
+
+
+
+_Want to change the button color? You can do so in the product settings!_
+
+Save, and move over to the “Audience” tab.
+
+### 3. Pre-segment your audience (coming soon)
+
+
+ ## Filter by attribute coming soon {{ class: "text-white" }}
+ We're working on pre-segmenting users by attributes. We will update this manual in the next days.
+
+
+Pre-segmentation isn't relevant for this survey because you likely want to solve all people who cancel their trial. You probably have a specific user action e.g. clicking on "Cancel Trial" you can use to only display the survey to users trialing your product.
+
+### 4. Set up a trigger for the Trial Conversion Survey:
+
+How you trigger your survey depends on your product. There are two options:
+
+1. **Trigger by pageURL:** Let’s say you have a page under “/trial-cancelled” where you forward users once they cancelled the trial subscription. You can then create an user Action with the type `pageURL` with the following settings:
+
+
+
+Whenever a user visits this page, the survey will be displayed ✅
+
+2. **Trigger by Button Click:** In a different case, you have a “Cancel Trial button in your app. You can setup a user Action with the according `innerText` like so:
+
+
+
+Please have a look at our complete [Actions manual](/docs/actions/why) if you have questions.
+
+### 5. Select Action in the “When to ask” card
+
+
+
+### 6. Last step: Set Recontact Options correctly
+
+Lastly, scroll down to “Recontact Options”. Here you have to choose the correct settings to make sure you gather as many insights as possible. You want to make sure that this survey is always displayed, no matter if the user has already seen a survey in the past days:
+
+
+
+### 7. Congrats! You’re ready to publish your survey 💃
+
+
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ You need to have the Formbricks Widget installed to display the Feedback Box in your app. Please follow [this
+ tutorial (Step 4 onwards)](/docs/getting-started/quickstart) to install the widget.
+
+
+###
+
+# Go get 'em 🎉
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/publish.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/publish.png
new file mode 100644
index 0000000000..a63538d6ee
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/publish.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/recontact-options.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/recontact-options.png
new file mode 100644
index 0000000000..cf0dcfb5b1
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/recontact-options.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/select-action.png b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/select-action.png
new file mode 100644
index 0000000000..ec3f22bec9
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/improve-trial-cr/select-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-css.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-css.png
new file mode 100644
index 0000000000..143c7a03e6
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-css.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-innertext.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-innertext.png
new file mode 100644
index 0000000000..7fb947ff8e
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-innertext.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-pageurl.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-pageurl.png
new file mode 100644
index 0000000000..791a6ab321
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/action-pageurl.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/add-action.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/add-action.png
new file mode 100644
index 0000000000..50306cece0
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/add-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/change-text.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/change-text.png
new file mode 100644
index 0000000000..e015f420d1
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/change-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/create-prompt.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/create-prompt.png
new file mode 100644
index 0000000000..a524548d42
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/create-prompt.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/interview-example.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/interview-example.png
new file mode 100644
index 0000000000..eaf773d974
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/interview-example.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/page.mdx b/apps/formbricks-com/app/docs/best-practices/interview-prompt/page.mdx
new file mode 100644
index 0000000000..cb194aa500
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/interview-prompt/page.mdx
@@ -0,0 +1,135 @@
+import DemoPreview from "@/components/dummyUI/DemoPreview";
+import Image from "next/image";
+
+import ActionCSS from "./action-css.png";
+import ActionInner from "./action-innertext.png";
+import ActionPageurl from "./action-pageurl.png";
+import AddAction from "./add-action.png";
+import ChangeText from "./change-text.png";
+import CreatePrompt from "./create-prompt.png";
+import InterviewExample from "./interview-example.png";
+import Publish from "./publish-survey.png";
+import RecontactOptions from "./recontact-options.png";
+import SelectAction from "./select-action.png";
+
+export const meta = {
+ title: "In-app Interview Prompt",
+ description: "Invite only power users to schedule an interview with your product team.",
+};
+
+[Best Practices]()
+
+# In-app Interview Prompt
+
+The Interview Prompt allows you to pick a specific user segment (e.g. Power Users) and invite them to a user interview. Bye, bye spammy email invites, benefit from up to 6x more respondents.
+
+## Purpose
+
+Product analytics and in-app surveys are incomplete without user interviews. Set the scheduling on autopilot for a continuous stream of interviews.
+
+## Preview
+
+
+
+## Formbricks Approach
+
+- Pre-segment users with custom attributes. Only invite highly relevant users.
+- In-app prompts have a 6x higher conversion rate than email invites.
+- Set scheduling user interviews on auto pilot.
+- Soon: Integrate directly with your [Cal.com](http://Cal.com) account.
+
+## Installation
+
+To display an Interview Prompt in your app you want to proceed as follows:
+
+1. Create new Interview Prompt at [app.formbricks.com](http://app.formbricks.com/)
+2. Adjust content and settings
+3. That’s it! 🎉
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ We assume that you have already installed the Formbricks Widget in your web app. It’s required to display messages
+ and surveys in your app. If not, please follow the [Quick Start Guide (15mins).](/docs/getting-started/quickstart)
+
+
+### 1. Create new Interview Prompt
+
+If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
+
+Click on "Create Survey" and choose the template “Interview Prompt”:
+
+
+
+### 2. Update prompt and CTA
+
+Update the prompt, description and button text to match your products tonality. You can also update the button color in the Product Settings.
+
+
+
+In the button settings you have to make sure it is set to “External URL”. In the URL field, copy your booking link (e.g. https://cal.com/company/user-interview). If you don’t have a booking link yet, head over to [cal.com](http://cal.com) and get one - they have the best free plan out there!
+
+
+
+Save, and move over to the “Audience” tab.
+
+### 3. Pre-segment your audience (coming soon)
+
+
+ ## Filter by attribute coming soon {{ class: "text-white" }}
+ We're working on pre-segmenting users by attributes. We will update this manual in the next few days.
+
+
+Once you clicked over to the “Audience” tab you can change the settings. In the **Who To Send** card, select “Filter audience by attribute”. This allows you to only show the prompt to a specific segment of your user base.
+
+In our case, we want to select users who we have assigned the attribute “Power User”. To learn how to assign attributes to your users, please [follow this guide](/docs/attributes/why).
+
+Great, now only the “Power User” segment will see our Interview Prompt. But when will they see it?
+
+### 4. Set up a trigger for the Interview Prompt:
+
+To create the trigger to show your Interview Prompt, go to the “Audience” tab, find the “When to send” card and choose “Add Action”. We will now use our super cool No-Code User Action Tracker:
+
+
+
+
+ ## You can also add actions in your code {{ class: "text-white" }}
+ You can also create [Code Actions](/docs/actions/code) using `formbricks.track("Eventname")` - they will automatically
+ appear in your Actions overview as long as the SDK is embedded.
+
+
+Generally, we have two types of user actions: Page views and clicks. The Interview Prompt, you’ll likely want to display on a page visit since you already filter who sees the prompt by attributes.
+
+1. **pageURL:** Whenever a user visits a page the survey will be displayed, as long as the other conditions match. Other conditions are pre-segmentation, if this user has seen a survey in the past 2 weeks, etc.
+
+
+
+2. **innerText & CSS-Selector:** When a user clicks an element (like a button) with a specific text content or CSS selector, the prompt will be displayed as long as the other conditions also match.
+
+
+
+
+
+
+### 5. Select action in the “When to ask” card
+
+
+
+### 6. Set Recontact Options correctly
+
+Scroll down to “Recontact Options”. Here you have to choose the correct settings to strike the right balance between asking for user feedback and preventing survey fatigue. Your settings also depend on the size of your user base or segment. If you e.g. have thousands of “Power Users” you can easily afford to only display the prompt once. If you have a smaller user base you might want to ask twice to get a sufficient amount of bookings:
+
+
+
+### 7. Congrats! You’re ready to publish your survey 💃 🤸
+
+
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ You need to have the Formbricks Widget installed to display the Feedback Box in your app. Please follow [this
+ tutorial (Step 4 onwards)](/docs/getting-started/quickstart) to install the widget.
+
+
+###
+
+# Learn about them users! 🎉
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/publish-survey.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/publish-survey.png
new file mode 100644
index 0000000000..3c05657fa1
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/publish-survey.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/recontact-options.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/recontact-options.png
new file mode 100644
index 0000000000..5d5d0b568d
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/recontact-options.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/interview-prompt/select-action.png b/apps/formbricks-com/app/docs/best-practices/interview-prompt/select-action.png
new file mode 100644
index 0000000000..f6967aa760
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/interview-prompt/select-action.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/action-css.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/action-css.png
new file mode 100644
index 0000000000..143c7a03e6
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/action-css.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/action-pageurl.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/action-pageurl.png
new file mode 100644
index 0000000000..791a6ab321
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/action-pageurl.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/change-text.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/change-text.png
new file mode 100644
index 0000000000..3fbf0184c4
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/change-text.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/create-survey.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/create-survey.png
new file mode 100644
index 0000000000..9fe5db384a
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/create-survey.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/page.mdx b/apps/formbricks-com/app/docs/best-practices/pmf-survey/page.mdx
new file mode 100644
index 0000000000..11c5c40253
--- /dev/null
+++ b/apps/formbricks-com/app/docs/best-practices/pmf-survey/page.mdx
@@ -0,0 +1,117 @@
+import DemoPreview from "@/components/dummyUI/DemoPreview";
+import Image from "next/image";
+
+import ActionCSS from "./action-css.png";
+import ActionPageurl from "./action-pageurl.png";
+import ChangeText from "./change-text.png";
+import CreateSurvey from "./create-survey.png";
+import Publish from "./publish.png";
+import RecontactOptions from "./recontact-options.png";
+import SelectAction from "./select-action.png";
+
+export const meta = {
+ title: "Product-Market Fit Survey",
+ description: "The Product-Market Fit survey helps you measure, well, Product-Market Fit (PMF).",
+};
+
+[Best Practices]()
+
+# Product-Market Fit Survey
+
+## Purpose
+
+Measuring and understanding your PMF is essential to build a large, successful business. It helps you understand what users like, what they’re missing and what to build next. This survey is perfectly suited to measure PMF like [Superhuman](https://review.firstround.com/how-superhuman-built-an-engine-to-find-product-market-fit).
+
+## Preview
+
+
+
+## Formbricks Approach
+
+- Pre-segment users to only survey users who have experienced your products value
+- Never ask twice, keep your data clean
+- Run on autopilot: Set up once, keep surveying users continuously
+
+## Overview
+
+To display the Product-Market Fit survey in your app you want to proceed as follows:
+
+1. Create new Product-Market Fit survey at [app.formbricks.com](http://app.formbricks.com/)
+2. Setup pre-segmentation to assure high data quality
+3. Setup the user action to display survey at good point in time
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ We assume that you have already installed the Formbricks Widget in your web app. It’s required to display messages
+ and surveys in your app. If not, please follow the [Quick Start Guide (15mins).](/docs/getting-started/quickstart)
+
+
+### 1. Create new PMF survey
+
+If you don't have an account yet, create one at [app.formbricks.com](https://app.formbricks.com/auth/signup)
+
+Click on "Create Survey" and choose one of the PMF survey templates. The first one is rather short, the latter builds on the ["Product-Market Fit Engine"](https://review.firstround.com/how-superhuman-built-an-engine-to-find-product-market-fit) developed by Superhuman:
+
+
+
+### 2. Update questions (if you like)
+
+You’re free to update the question and answer options. However, based on our experience, we suggest giving the provided template a go 😊 Here is a very [detailed description](https://coda.io/@rahulvohra/superhuman-product-market-fit-engine) of what to do with the data you’re collecting.
+
+
+
+_Want to change the button color? You can do so in the product settings!_
+
+Save, and move over to where the magic happens: The “Audience” tab.
+
+### 3. Pre-segment your audience (coming soon)
+
+
+ ## Filter by attribute coming soon {{ class: "text-white" }}
+ We're working on pre-segmenting users by attributes. We will update this manual in the next days.
+
+
+To run this survey properly, you should pre-segment your user base. As touched upon earlier: if you ask every user you’ll get lots of opinions which are often misleading. You only want to gather feedback from people who invested the time to get to know and use your product:
+
+**Filter by attribute**: You can keep the logic to decide if a user has (or has not) experienced value in your application. This makes most sense if you want to use historic usage data to decide if a user qualifies or not. Create your logic and if it applies, send an attribute to Formbricks by e.g. `formbricks.setAttribute("Loyalty", "Experienced Value");` Here is the full manual on how to [set attributes](/docs/attributes/custom-attributes).
+
+**Filter by actions (coming soon)**: Later, you can also segment users based on events tracked with Formbricks. However, this makes it impossible to use historic usage data (pre Formbricks usage). Here we will have a few options to achieve that:
+
+- Check the time passed since sign-up (e.g. signed up 4 weeks ago)
+- User has performed a specific action a certain number of times or (e.g. created 5 reports)
+- User has performed a combination of actions (e.g. created a report **and** invited a team member)
+
+This way you make sure that you separate potentially misleading opinions from valuable insights.
+
+### 4. Set up a trigger for the Product-Market Fit survey:
+
+You need a trigger to display the survey but in this case, the filtering does all the work. It’s up to you to decide to display the survey after the user viewed a specific subpage (pageURL) or after clicking an element. Have a look at the [Actions manual](/docs/actions/why) if you are not sure how to set them up:
+
+
+
+
+
+
+### 5. Select Action in the “When to ask” card
+
+
+
+### 6. Last step: Set Recontact Options correctly
+
+Lastly, scroll down to “Recontact Options”. Here you have to choose the correct settings to make sure your data remains of high quality. You want to make sure that this survey is only responded to once per user. It is up to you to decide if you want to display it several times until the user responds:
+
+
+
+### 7. Congrats! You’re ready to publish your survey 💃
+
+
+
+
+ ## Formbricks Widget running? {{ class: "text-white" }}
+ You need to have the Formbricks Widget installed to display the Feedback Box in your app. Please follow [this
+ tutorial (Step 4 onwards)](/docs/getting-started/quickstart) to install the widget.
+
+
+###
+
+# Get those insights!
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/publish.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/publish.png
new file mode 100644
index 0000000000..42bbc5f2bd
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/publish.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/recontact-options.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/recontact-options.png
new file mode 100644
index 0000000000..5d5d0b568d
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/recontact-options.png differ
diff --git a/apps/formbricks-com/app/docs/best-practices/pmf-survey/select-action.png b/apps/formbricks-com/app/docs/best-practices/pmf-survey/select-action.png
new file mode 100644
index 0000000000..f6967aa760
Binary files /dev/null and b/apps/formbricks-com/app/docs/best-practices/pmf-survey/select-action.png differ
diff --git a/apps/formbricks-com/app/docs/client-api/create-response/page.mdx b/apps/formbricks-com/app/docs/client-api/create-response/page.mdx
new file mode 100644
index 0000000000..f9bab88466
--- /dev/null
+++ b/apps/formbricks-com/app/docs/client-api/create-response/page.mdx
@@ -0,0 +1,116 @@
+export const meta = {
+ title: "API: Create response",
+ description: "Learn how to create a new response to a survey via API.",
+};
+
+[Client API]()
+
+# API: Create Response
+
+## Create a response {{ tag: 'POST', label: '/api/v1/client/responses' }}
+
+Add a new response to a survey.
+
+
+
+
+ ### Mandatory Body Fields
+
+
+
+ The id of the survey the response belongs to.
+
+
+ Marks whether the response is complete or not.
+
+
+ The data of the response as JSON object (key: questionId, value: answer).
+
+
+
+
+ ### Optional Body Fields
+
+
+
+ Internal Formbricks id to identify the user sending the response
+
+
+
+### Parameters Explained
+
+| field name | required | default | description |
+| ---------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
+| data | yes | - | The response data object (answers to the survey). In this object the key is the questionId, the value the answer of the user to this question. |
+| personId | no | - | The person this response is connected to. |
+| surveyId | yes | - | The survey this response is connected to. |
+| finished | yes | false | Mark a response as complete to be able to filter accordingly. |
+
+
+
+
+
+
+ ```bash {{ title: 'cURL' }}
+ curl --location --request POST 'https://app.formbricks.com/api/v1/client/responses' \
+ --data-raw '{
+ "surveyId":"clfqz1esd0000yzah51trddn8",
+ "personId": "clfqjny0v000ayzgsycx54a2c",
+ "finished": true,
+ "data": {
+ "clfqjny0v0003yzgscnog1j9i": 10,
+ "clfqjtn8n0070yzgs6jgx9rog": "I love Formbricks"
+ }
+ }'
+ ```
+
+ ```json {{ title: 'Example Request Body' }}
+ {
+ "personId": "clfqjny0v000ayzgsycx54a2c",
+ "surveyId": "clfqz1esd0000yzah51trddn8",
+ "finished": true,
+ "data": {
+ "clfqjny0v0003yzgscnog1j9i": 10,
+ "clfqjtn8n0070yzgs6jgx9rog": "I love Formbricks"
+ }
+ }
+ ```
+
+
+
+
+
+ ```json {{ title: '200 Success' }}
+ {
+ "data": {
+ "id": "clisyqeoi000219t52m5gopke",
+ "surveyId": "clfqz1esd0000yzah51trddn8",
+ "finished": true,
+ "person": {
+ "id": "clfqjny0v000ayzgsycx54a2c",
+ "attributes": {
+ "email": "me@johndoe.com"
+ }
+ },
+ "data": {
+ "clfqjny0v0003yzgscnog1j9i": 10,
+ "clfqjtn8n0070yzgs6jgx9rog": "I love Formbricks"
+ }
+ }
+ }
+ ```
+
+ ```json {{ title: '400 Bad Request' }}
+ {
+ "code": "bad_request",
+ "message": "surveyId was not provided.",
+ "details": {
+ "surveyId": "This field is required."
+ }
+ }
+ ```
+
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/client-api/overview/page.mdx b/apps/formbricks-com/app/docs/client-api/overview/page.mdx
new file mode 100644
index 0000000000..b065a4dd99
--- /dev/null
+++ b/apps/formbricks-com/app/docs/client-api/overview/page.mdx
@@ -0,0 +1,13 @@
+import { Fence } from "@/components/shared/Fence";
+
+export const meta = {
+ title: "Client API Overview",
+ description:
+ "Explore the Formbricks Public Client API for client-side tasks and integration into your website.",
+};
+
+[Client API]()
+
+# Client API Overview
+
+The Public Client API is designed for the JavaScript SDK and does not require authentication. It's primarily used for creating persons, sessions, and responses within the Formbricks platform. This API is ideal for client-side interactions, as it doesn't expose sensitive information.
diff --git a/apps/formbricks-com/app/docs/client-api/update-response/page.mdx b/apps/formbricks-com/app/docs/client-api/update-response/page.mdx
new file mode 100644
index 0000000000..cad8d5ccac
--- /dev/null
+++ b/apps/formbricks-com/app/docs/client-api/update-response/page.mdx
@@ -0,0 +1,103 @@
+export const meta = {
+ title: "API: Update submission",
+ description: "Learn how to update a new response to a survey via API.",
+};
+
+[Client API]()
+
+# API: Update Response
+
+Update an existing response in a survey.
+
+
+
+
+ ### Mandatory Body Fields
+
+
+
+ The data of the response as JSON object (key: questionId, value: answer).
+
+
+
+### Parameters Explained
+
+| field name | required | default | description |
+| ---------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
+| data | yes | - | The response data object (answers to the survey). In this object the key is the questionId, the value the answer of the user to this question. |
+| finished | yes | false | Mark a response as complete to be able to filter accordingly. |
+
+
+
+
+
+
+ ```bash {{ title: 'cURL' }}
+ curl --location --request POST 'https://app.formbricks.com/api/v1/client/responses/[responseId]' \
+ --data-raw '{
+ "personId": "clfqjny0v000ayzgsycx54a2c",
+ "surveyId": "clfqz1esd0000yzah51trddn8",
+ "finished": true,
+ "data": {
+ "clggpvpvu0009n40g8ikawby8": 5,
+ }
+ }'
+ ```
+
+ ```json {{ title: 'Example Request Body' }}
+ {
+ "personId": "clfqjny0v000ayzgsycx54a2c",
+ "surveyId": "clfqz1esd0000yzah51trddn8",
+ "finished": true,
+ "data": {
+ "clggpvpvu0009n40g8ikawby8": 5,
+ }
+ }
+ ```
+
+
+
+
+
+ ```json {{ title: '200 Success' }}
+ {
+ "data": {
+ "id": "clisyqeoi000219t52m5gopke",
+ "surveyId": "clfqz1esd0000yzah51trddn8",
+ "finished": true,
+ "person": {
+ "id": "clfqjny0v000ayzgsycx54a2c",
+ "attributes": {
+ "email": "me@johndoe.com"
+ }
+ },
+ "data": {
+ "clfqjny0v0003yzgscnog1j9i": 10,
+ "clfqjtn8n0070yzgs6jgx9rog": "I love Formbricks",
+ "clggpvpvu0009n40g8ikawby8": 5
+ }
+ }
+ }
+ ```
+
+ ```json {{ title: '400 Bad Request' }}
+ {
+ "code": "bad_request",
+ "message": "data was not provided.",
+ "details": {
+ "data": "This field is required."
+ }
+ }
+ ```
+
+ ```json {{ title: '404 Not Found' }}
+ {
+ "code": "not_found",
+ "message": "Response not found"
+ }
+ ```
+
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/contacts/page.mdx b/apps/formbricks-com/app/docs/contacts/page.mdx
deleted file mode 100644
index b75afa9a9f..0000000000
--- a/apps/formbricks-com/app/docs/contacts/page.mdx
+++ /dev/null
@@ -1,394 +0,0 @@
-export const metadata = {
- title: 'Contacts',
- description:
- 'On this page, we’ll dive into the different contact endpoints you can use to manage contacts programmatically.',
-}
-
-# Contacts
-
-As the name suggests, contacts are a core part of Protocol — the very reason Protocol exists is so you can have secure conversations with your contacts. On this page, we'll dive into the different contact endpoints you can use to manage contacts programmatically. We'll look at how to query, create, update, and delete contacts. {{ className: 'lead' }}
-
-## The contact model
-
-The contact model contains all the information about your contacts, such as their username, avatar, and phone number. It also contains a reference to the conversation between you and the contact and information about when they were last active on Protocol.
-
-### Properties
-
-
-
- Unique identifier for the contact.
-
-
- The username for the contact.
-
-
- The phone number for the contact.
-
-
- The avatar image URL for the contact.
-
-
- The contact display name in the contact list. By default, this is just the
- username.
-
-
- Unique identifier for the conversation associated with the contact.
-
-
- Timestamp of when the contact was last active on the platform.
-
-
- Timestamp of when the contact was created.
-
-
-
----
-
-## List all contacts {{ tag: 'GET', label: '/v1/contacts' }}
-
-
-
-
- This endpoint allows you to retrieve a paginated list of all your contacts. By default, a maximum of ten contacts are shown per page.
-
- ### Optional attributes
-
-
-
- Limit the number of contacts returned.
-
-
-
-
-
-
- This endpoint allows you to add a new contact to your contact list in Protocol. To add a contact, you must provide their Protocol username and phone number.
-
- ### Required attributes
-
-
-
- The username for the contact.
-
-
- The phone number for the contact.
-
-
-
- ### Optional attributes
-
-
-
- The avatar image URL for the contact.
-
-
- The contact display name in the contact list. By default, this is just the username.
-
-
-
-
-
-
- This endpoint allows you to retrieve a contact by providing their Protocol id. Refer to [the list](#the-contact-model) at the top of this page to see which properties are included with contact objects.
-
-
-
-
- This endpoint allows you to perform an update on a contact. Currently, the only attribute that can be updated on contacts is the `display_name` attribute which controls how a contact appears in your contact list in Protocol.
-
- ### Optional attributes
-
-
-
- The contact display name in the contact list. By default, this is just the username.
-
-
-
-
-
-
- This endpoint allows you to delete contacts from your contact list in Protocol. Note: This will also delete your conversation with the given contact.
-
-
-
-
-
-
- ```bash {{ title: 'cURL' }}
- curl -X DELETE https://api.protocol.chat/v1/contacts/WAz8eIbvDR60rouK \
- -H "Authorization: Bearer {token}"
- ```
-
- ```js
- import ApiClient from '@example/protocol-api'
-
- const client = new ApiClient(token)
-
- await client.contacts.delete('WAz8eIbvDR60rouK')
- ```
-
- ```python
- from protocol_api import ApiClient
-
- client = ApiClient(token)
-
- client.contacts.delete("WAz8eIbvDR60rouK")
- ```
-
- ```php
- $client = new \Protocol\ApiClient($token);
-
- $client->contacts->delete('WAz8eIbvDR60rouK');
- ```
-
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/contributing/demo/demoapp.png b/apps/formbricks-com/app/docs/contributing/demo/demoapp.png
new file mode 100644
index 0000000000..b3f657a420
Binary files /dev/null and b/apps/formbricks-com/app/docs/contributing/demo/demoapp.png differ
diff --git a/apps/formbricks-com/app/docs/contributing/demo/page.mdx b/apps/formbricks-com/app/docs/contributing/demo/page.mdx
new file mode 100644
index 0000000000..bdf115c92f
--- /dev/null
+++ b/apps/formbricks-com/app/docs/contributing/demo/page.mdx
@@ -0,0 +1,66 @@
+import Image from "next/image";
+
+import DemoApp from "./demoapp.png";
+
+export const meta = {
+ title: "Demo App",
+ description: "To test in-app surveys, trigger actions and set attributes, you can use the Demo App.",
+};
+
+[Contributing]()
+
+# Demo App
+
+To play around with the in-app [User Actions](/docs/actions/why), you can use the Demo App. It's a simple React app that you can run locally and use to trigger actions and set [Attributes](/docs/attributes/why).
+
+
+
+## Functionality
+
+### Code Action
+
+This button sends a Code Action to the Formbricks API called 'Code Action'. You will find it in the Actions Tab.
+
+```tsx
+formbricks.track("Code Action");
+```
+
+### No Code Action
+
+This button sends a No Code Action as long as you created it beforehand in the Formbricks App. For it to work, you need to add the No Code Action within Formbricks.
+
+```tsx
+
+```
+
+### Set Plan to "Free"
+
+This button sets the attribute 'Plan' to 'Free'. If the attribute does not exist, it creates it.
+
+```tsx
+formbricks.setAttribute("Plan", "Free");
+```
+
+### Set Plan to "Paid"
+
+This button sets the attribute 'Plan' to 'Paid'. If the attribute does not exist, it creates it.
+
+```tsx
+formbricks.setAttribute("Plan", "Paid");
+```
+
+### Set Email
+
+This button sets the user email 'test@web.com'
+
+```tsx
+formbricks.setEmail("test@web.com");
+```
+
+### Set UserId
+
+This button sets an external user ID to 'THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING'
+
+```tsx
+formbricks.setUserId("THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING");
+```
diff --git a/apps/formbricks-com/app/docs/contributing/introduction/page.mdx b/apps/formbricks-com/app/docs/contributing/introduction/page.mdx
new file mode 100644
index 0000000000..08672737c2
--- /dev/null
+++ b/apps/formbricks-com/app/docs/contributing/introduction/page.mdx
@@ -0,0 +1,38 @@
+export const meta = {
+ title: "Contribution Guide",
+ description: "How to contribute to Formbricks",
+};
+
+[Contributing]()
+
+# Contribution Guide
+
+We are so happy that you are interested in contributing to Formbricks 🤗
+
+There are many ways to contribute to Formbricks with writing Issues, fixing bugs, building new features or updating the docs.
+
+## Issues
+
+Spotted a bug? Has deployment gone wrong? Do you have user feedback? [Raise an issue](https://github.com/formbricks/formbricks/issues/new/choose) for the fastest response.
+
+... or pick up and fix an issue if you want to do a Pull Request.
+
+## Feature requests
+
+Raise an issue for these and tag it as an Enhancement. We love every idea. Please give us as much context on the why as possible.
+
+## Creating a PR
+
+Please fork the repository, make your changes and create a new pull request if you want to make an update.
+
+If you want to speak to us before doing lots of work, please join our [Discord server](https://formbricks.com/discord) and tell us what you would like to work on - we're very responsive and friendly!
+
+For QA of your Pull-Request, you can also get in touch with Matti on Discord. But we will also get to your PR without you taking additional action ;-)
+
+## Features
+
+We are currently working on having a clear [Roadmap](https://github.com/formbricks/formbricks) for the next steps ahead.
+
+But you can also pick a feature that is not already on the roadmap if you think it creates a positive impact for Formbricks.
+
+If you are at all unsure, just raise it as an enhancement issue first and tell us that you like to work on it, and we'll very quickly respond.
diff --git a/apps/formbricks-com/app/docs/contributing/setup/page.mdx b/apps/formbricks-com/app/docs/contributing/setup/page.mdx
new file mode 100644
index 0000000000..5c3793a8de
--- /dev/null
+++ b/apps/formbricks-com/app/docs/contributing/setup/page.mdx
@@ -0,0 +1,81 @@
+export const meta = {
+ title: "Setup Dev Environment",
+ description: "Setup a development environment for Formbricks.",
+};
+
+[Contributing]()
+
+# Setup Dev Environment
+
+To get the project running locally on your machine you need to have the following development tools installed:
+
+- Node.JS (we recommend v18)
+- [pnpm](https://pnpm.io/)
+- [Docker](https://www.docker.com/) (to run PostgreSQL / MailHog)
+
+1. Clone the project:
+
+ ```bash
+ git clone https://github.com/formbricks/formbricks
+ ```
+
+ and move into the directory
+
+ ```bash
+ cd formbricks
+ ```
+
+1. Install Node.JS packages via pnpm. Don't have pnpm? Get it [here](https://pnpm.io/installation)
+
+ ```bash
+ pnpm install
+ ```
+
+1. Create a `.env` file based on `.env.example`. It's already preset to work with the docker-compose setup but you can also change values if needed.
+
+ ```bash
+ cp .env.example .env
+ ```
+
+1. Make sure you have [`Docker`](https://docs.docker.com/compose/) & [`docker-compose`](https://docs.docker.com/compose/) installed and running on your machine. Then run the following command to start the formbricks dev setup:
+
+ ```bash
+ pnpm go
+ ```
+
+ This starts the Formbricks main app (plus all its dependencies) as well as the following services using Docker:
+
+ - a `postgres` container for hosting your database,
+ - a `mailhog` container that acts as a mock SMTP server and shows received mails in a web UI (forwarded to your host's `localhost:8025`)
+
+ **You can now access the Formbricks app on [http://localhost:3000](http://localhost:3000)**. You will be automatically redirected to the login. To use your local installation of formbricks, create a new account.
+
+ For viewing the confirmation email and other emails the system sends you, you can access mailhog at [http://localhost:8025](http://localhost:8025)
+
+### Build
+
+To build all apps and packages and check for build errors, run the following command:
+
+```bash
+pnpm build
+```
+
+### Access Demo app
+
+To run the [Demo app](/docs/contributing/demo), run the following command in a separate terminal window:
+
+```bash
+pnpm dev --filter=demo
+```
+
+You can now access the Demo app on [http://localhost:3002](http://localhost:3002).
+
+### Access Formbricks website
+
+If you want to make changes to the Formbricks website, e.g. to update the documentation, run the following command in a separate terminal window:
+
+```bash
+pnpm dev --filter=formbricks-com
+```
+
+You can now access the Formbricks website on [http://localhost:3001](http://localhost:3001).
diff --git a/apps/formbricks-com/app/docs/contributing/troubleshooting/clear-app-data.png b/apps/formbricks-com/app/docs/contributing/troubleshooting/clear-app-data.png
new file mode 100644
index 0000000000..31e6ee9fcb
Binary files /dev/null and b/apps/formbricks-com/app/docs/contributing/troubleshooting/clear-app-data.png differ
diff --git a/apps/formbricks-com/app/docs/contributing/troubleshooting/logout.png b/apps/formbricks-com/app/docs/contributing/troubleshooting/logout.png
new file mode 100644
index 0000000000..8ff41bcfc6
Binary files /dev/null and b/apps/formbricks-com/app/docs/contributing/troubleshooting/logout.png differ
diff --git a/apps/formbricks-com/app/docs/contributing/troubleshooting/page.mdx b/apps/formbricks-com/app/docs/contributing/troubleshooting/page.mdx
new file mode 100644
index 0000000000..3b974d2fd3
--- /dev/null
+++ b/apps/formbricks-com/app/docs/contributing/troubleshooting/page.mdx
@@ -0,0 +1,64 @@
+import Image from "next/image";
+
+import ClearAppData from "./clear-app-data.png";
+import UncaughtPromise from "./uncaught-promise.png";
+import Logout from "./logout.png";
+
+export const meta = {
+ title: "Troubleshooting",
+ description:
+ "Formbricks is a complex application in constant development. Sometimes, things don't go as planned. Here are some tips to help you troubleshoot.",
+};
+
+[Contributing]()
+
+# Troubleshooting
+
+Here you'll find help with Frequently Recurring Problems
+
+## "The app doesn't work after doing a prisma migration"
+
+This can happen but fear not, the fix is easy: Delete the application storage of your browser and reload the page. This will force the app to re-fetch the data from the server:
+
+
+
+## "I ran 'pnpm i' but there seems to be an error with the packages"
+
+If nothing helps, run `pnpm clean` and then `pnpm i` again. This solves a lot.
+
+## "I get a full-screen error with cryptic strings"
+
+This usually happens when the Formbricks Widget wasn't correctly or completely built.
+
+```bash
+// Build formbricks-js first
+pnpm build --filter=js
+
+// Run the app again
+pnpm dev
+```
+
+## My machine struggles with the repository
+
+Since we're working with a monorepo structure, the repository can get quite big. If you're having trouble working with the repository, try the following:
+
+```bash
+// Only run the Formbricks app
+pnpm dev --filter=web...
+
+// Only run the landing page app
+pnpm dev --filter=formbricks-com...
+
+// Only run the demo app
+pnpm dev --filter=demo...
+```
+
+However, in our experience it's better to run `pnpm dev` than having two terminals open (one with the Formbricks app and one with the demo).
+
+## Uncaught (in promise) SyntaxError: Unexpected token !DOCTYPE ... is not valid JSON
+
+
+
+This happens when you're using the Demo App and delete the Person within the Formbricks app which the widget is currently connected with. We're fixing it, but you can also just logout your test person and reload the page to get rid of it.
+
+
diff --git a/apps/formbricks-com/app/docs/contributing/troubleshooting/uncaught-promise.png b/apps/formbricks-com/app/docs/contributing/troubleshooting/uncaught-promise.png
new file mode 100644
index 0000000000..d424bef970
Binary files /dev/null and b/apps/formbricks-com/app/docs/contributing/troubleshooting/uncaught-promise.png differ
diff --git a/apps/formbricks-com/app/docs/conversations/page.mdx b/apps/formbricks-com/app/docs/conversations/page.mdx
deleted file mode 100644
index 87fae527ab..0000000000
--- a/apps/formbricks-com/app/docs/conversations/page.mdx
+++ /dev/null
@@ -1,407 +0,0 @@
-export const metadata = {
- title: 'Conversations',
- description:
- 'On this page, we’ll dive into the different conversation endpoints you can use to manage conversations programmatically.',
-}
-
-# Conversations
-
-Conversations are an essential part of Protocol — they are the containers for the messages between you, your contacts, and groups. On this page, we’ll dive into the different conversation endpoints you can use to manage conversations programmatically. We'll look at how to query, create, update, and delete conversations. {{ className: 'lead' }}
-
-## The conversation model
-
-The conversation model contains all the information about the conversations between you and your contacts. In addition, conversations can also be group-based with more than one contact, they can have a pinned message, and they can be muted.
-
-### Properties
-
-
-
- Unique identifier for the conversation.
-
-
- Unique identifier for the other contact in the conversation.
-
-
- Unique identifier for the group that the conversation belongs to.
-
-
- Unique identifier for the pinned message.
-
-
- Whether or not the conversation has been pinned.
-
-
- Whether or not the conversation has been muted.
-
-
- Timestamp of when the conversation was last active.
-
-
- Timestamp of when the conversation was last opened by the authenticated
- user.
-
-
- Timestamp of when the conversation was created.
-
-
- Timestamp of when the conversation was archived.
-
-
-
----
-
-## List all conversations {{ tag: 'GET', label: '/v1/conversations' }}
-
-
-
-
- This endpoint allows you to retrieve a paginated list of all your conversations. By default, a maximum of ten conversations are shown per page.
-
- ### Optional attributes
-
-
-
- Limit the number of conversations returned.
-
-
- Only show conversations that are muted when set to `true`.
-
-
- Only show conversations that are archived when set to `true`.
-
-
- Only show conversations that are pinned when set to `true`.
-
-
- Only show conversations for the specified group.
-
-
-
-
-
-
- This endpoint allows you to add a new conversation between you and a contact or group. A contact or group id is required to create a conversation.
-
- ### Required attributes
-
-
-
- Unique identifier for the other contact in the conversation.
-
-
- Unique identifier for the group that the conversation belongs to.
-
-
-
-
-
-
- This endpoint allows you to retrieve a conversation by providing the conversation id. Refer to [the list](#the-conversation-model) at the top of this page to see which properties are included with conversation objects.
-
-
-
-
- This endpoint allows you to perform an update on a conversation. Examples of updates are pinning a message, muting or archiving the conversation, or pinning the conversation itself.
-
- ### Optional attributes
-
-
-
- Unique identifier for the pinned message.
-
-
- Whether or not the conversation has been pinned.
-
-
- Whether or not the conversation has been muted.
-
-
- Timestamp of when the conversation was archived.
-
-
-
-
-
-
- This endpoint allows you to delete your conversations in Protocol. Note: This will permanently delete the conversation and all its messages — archive it instead if you want to be able to restore it later.
-
-
-
-
-
-
- ```bash {{ title: 'cURL' }}
- curl -X DELETE https://api.protocol.chat/v1/conversations/xgQQXg3hrtjh7AvZ \
- -H "Authorization: Bearer {token}"
- ```
-
- ```js
- import ApiClient from '@example/protocol-api'
-
- const client = new ApiClient(token)
-
- await client.conversations.delete('xgQQXg3hrtjh7AvZ')
- ```
-
- ```python
- from protocol_api import ApiClient
-
- client = ApiClient(token)
-
- client.conversations.delete("xgQQXg3hrtjh7AvZ")
- ```
-
- ```php
- $client = new \Protocol\ApiClient($token);
-
- $client->conversations->delete('xgQQXg3hrtjh7AvZ');
- ```
-
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/errors/page.mdx b/apps/formbricks-com/app/docs/errors/page.mdx
deleted file mode 100644
index 15f070b4e4..0000000000
--- a/apps/formbricks-com/app/docs/errors/page.mdx
+++ /dev/null
@@ -1,70 +0,0 @@
-export const metadata = {
- title: 'Errors',
- description:
- 'In this guide, we will talk about what happens when something goes wrong while you work with the API.',
-}
-
-# Errors
-
-In this guide, we will talk about what happens when something goes wrong while you work with the API. Mistakes happen, and mostly they will be yours, not ours. Let's look at some status codes and error types you might encounter. {{ className: 'lead' }}
-
-You can tell if your request was successful by checking the status code when receiving an API response. If a response comes back unsuccessful, you can use the error type and error message to figure out what has gone wrong and do some rudimentary debugging (before contacting support).
-
-
- Before reaching out to support with an error, please be aware that 99% of all
- reported errors are, in fact, user errors. Therefore, please carefully check
- your code before contacting Protocol support.
-
-
----
-
-## Status codes
-
-Here is a list of the different categories of status codes returned by the Protocol API. Use these to understand if a request was successful.
-
-
-
- A 2xx status code indicates a successful response.
-
-
- A 4xx status code indicates a client error — this means it's a _you_
- problem.
-
-
- A 5xx status code indicates a server error — you won't be seeing these.
-
-
-
----
-
-## Error types
-
-
-
-
- Whenever a request is unsuccessful, the Protocol API will return an error response with an error type and message. You can use this information to understand better what has gone wrong and how to fix it. Most of the error messages are pretty helpful and actionable.
-
- Here is a list of the two error types supported by the Protocol API — use these to understand what you have done wrong.
-
-
-
- This means that we made an error, which is highly speculative and unlikely.
-
-
- This means that you made an error, which is much more likely.
-
-
-
-
-
-
- ```bash {{ title: "Error response" }}
- {
- "type": "api_error",
- "message": "No way this is happening!?",
- "documentation_url": "https://protocol.chat/docs/errors/api_error"
- }
- ```
-
-
-
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-app/env-id.png b/apps/formbricks-com/app/docs/getting-started/nextjs-app/env-id.png
new file mode 100644
index 0000000000..d342241df4
Binary files /dev/null and b/apps/formbricks-com/app/docs/getting-started/nextjs-app/env-id.png differ
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-app/page.mdx b/apps/formbricks-com/app/docs/getting-started/nextjs-app/page.mdx
new file mode 100644
index 0000000000..57292575b0
--- /dev/null
+++ b/apps/formbricks-com/app/docs/getting-started/nextjs-app/page.mdx
@@ -0,0 +1,96 @@
+import Image from "next/image";
+
+import SetupChecklist from "./env-id.png";
+import WidgetNotConnected from "./widget-not-connected.png";
+import WidgetConnected from "./widget-connected.png";
+
+export const meta = {
+ title: "Setting up Formbricks SDK with Next.js App Directory",
+ description:
+ "Setting up Formbricks with the new Next.js 13 App Directory can be tricky. Follow this guide to make sure you get it right.",
+};
+
+[Getting Started](#)
+
+# Setting up Formbricks SDK with Next.js App Directory
+
+This guide will walk you through the process of integrating the Formbricks SDK into a Next.js application using the new app directory. As the Formbricks SDK only works on the client side, it's essential to ensure proper integration to avoid any issues.
+
+## Prerequisites
+
+Before getting started, make sure you have:
+
+1. A Next.js application set up and running.
+2. A Formbricks account with access to your environment ID and API host. You can find these in the **Setup Checklist** in the Settings:
+
+
+
+## Installing Formbricks SDK
+
+First, you need to install the Formbricks SDK using one of the following commands:
+
+```bash
+npm install --save @formbricks/js
+# or
+yarn add @formbricks/js
+# or
+pnpm add @formbricks/js
+```
+
+## Integrating with Next.js 13 App Directory
+
+The Next.js 13 app directory requires us to initialize Formbricks differently than the pages directory. Specifically, the app directory server-side renders components by default, and the formbricks-js library is a client-side library. To make these work together, create a `formbricks.tsx` file (or `formbricks.js` if you don't use Typescript) and set up the FormbricksProvider with the 'use client' directive:
+
+```tsx
+// app/formbricks.tsx
+"use client";
+import formbricks from "@formbricks/js";
+import { usePathname, useSearchParams } from "next/navigation";
+import { useEffect } from "react";
+
+export default function FormbricksProvider() {
+ const pathname = usePathname();
+ const searchParams = useSearchParams();
+
+ useEffect(() => {
+ formbricks.init({
+ environmentId: "clj66eqzu00m5qu0g8leglrns",
+ apiHost: "https://app.formbricks.com", // e.g. https://app.formbricks.com
+ debug: true, // remove when in production
+ });
+ }, []);
+
+ useEffect(() => {
+ formbricks?.registerRouteChange();
+ }, [pathname, searchParams]);
+
+ return null;
+}
+```
+
+Once we do this, we can then import the `formbricks.tsx` file in our `app/layout.tsx` file, and wrap our app in the Formbricks provider.
+
+```tsx
+// app/layout.tsx
+import FormbricksProvider from "./formbricks";
+import "./globals.css";
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+ {children}
+
+ );
+}
+```
+
+## Validate your setup
+
+Once you have completed the steps above, you can validate your setup by checking the **Setup Checklist** in the Settings. Your widget status indicator should go from this:
+
+
+
+To this:
+
+
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-app/widget-connected.png b/apps/formbricks-com/app/docs/getting-started/nextjs-app/widget-connected.png
new file mode 100644
index 0000000000..01d7595cdc
Binary files /dev/null and b/apps/formbricks-com/app/docs/getting-started/nextjs-app/widget-connected.png differ
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-app/widget-not-connected.png b/apps/formbricks-com/app/docs/getting-started/nextjs-app/widget-not-connected.png
new file mode 100644
index 0000000000..afd6d9aa60
Binary files /dev/null and b/apps/formbricks-com/app/docs/getting-started/nextjs-app/widget-not-connected.png differ
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-pages/env-id.png b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/env-id.png
new file mode 100644
index 0000000000..d342241df4
Binary files /dev/null and b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/env-id.png differ
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-pages/page.mdx b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/page.mdx
new file mode 100644
index 0000000000..183e550ada
--- /dev/null
+++ b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/page.mdx
@@ -0,0 +1,89 @@
+import Image from "next/image";
+
+import SetupChecklist from "./env-id.png";
+import WidgetNotConnected from "./widget-not-connected.png";
+import WidgetConnected from "./widget-connected.png";
+
+export const meta = {
+ title: "Setting up Formbricks SDK with Next.js Pages Directory",
+ description:
+ "Setting up Formbricks with the new Next.js 13 Pages Directory can be tricky. Follow this guide to make sure you get it right.",
+};
+
+[Getting Started](#)
+
+# Setting up Formbricks SDK with Next.js Pages Directory
+
+This guide will walk you through the process of integrating the Formbricks SDK into a Next.js application using the Pages Directory. As the Formbricks SDK only works on the client side, it's essential to ensure proper integration to avoid any issues.
+
+## Prerequisites
+
+Before getting started, make sure you have:
+
+1. A Next.js application with Pages Directory set up and running.
+2. A Formbricks account with access to your environment ID and API host. You can find these in the **Setup Checklist** in the Settings:
+
+
+
+## Installing Formbricks SDK
+
+First, you need to install the Formbricks SDK using one of the following commands:
+
+```bash
+npm install --save @formbricks/js
+# or
+yarn add @formbricks/js
+# or
+pnpm add @formbricks/js
+```
+
+## Integrating with Next.js 13 Pages Directory
+
+Update your Pages component in the \_app.ts file like so:
+
+```tsx
+import "@/styles/globals.css";
+import type { PagesProps } from "next/app";
+import { useEffect } from "react";
+import { useRouter } from "next/router";
+import formbricks from "@formbricks/js";
+
+if (typeof window !== "undefined") {
+ formbricks.init({
+ environmentId: "your-environment-id",
+ apiHost: "your-api-host", // e.g. https://app.formbricks.com
+ debug: true, // remove when in production
+ });
+}
+
+export default function Pages({ Component, pageProps }: PagesProps) {
+ const router = useRouter();
+
+ useEffect(() => {
+ // Connect next.js router to Formbricks
+ const handleRouteChange = formbricks?.registerRouteChange;
+ router.events.on("routeChangeComplete", handleRouteChange);
+
+ return () => {
+ router.events.off("routeChangeComplete", handleRouteChange);
+ };
+ }, []);
+
+ return ;
+}
+```
+
+## What are we doing here?
+
+1. First we need to initialize the Formbricks SDK, making sure it only runs on the client side.
+2. To connect the Next.js router to Formbricks and ensure the SDK can keep track of every page change, we are registering the route change event.
+
+## Validate your setup
+
+Once you have completed the steps above, you can validate your setup by checking the **Setup Checklist** in the Settings. Your widget status indicator should go from this:
+
+
+
+To this:
+
+
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-pages/widget-connected.png b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/widget-connected.png
new file mode 100644
index 0000000000..01d7595cdc
Binary files /dev/null and b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/widget-connected.png differ
diff --git a/apps/formbricks-com/app/docs/getting-started/nextjs-pages/widget-not-connected.png b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/widget-not-connected.png
new file mode 100644
index 0000000000..afd6d9aa60
Binary files /dev/null and b/apps/formbricks-com/app/docs/getting-started/nextjs-pages/widget-not-connected.png differ
diff --git a/apps/formbricks-com/app/docs/getting-started/quickstart/page.mdx b/apps/formbricks-com/app/docs/getting-started/quickstart/page.mdx
new file mode 100644
index 0000000000..0b02b7c010
--- /dev/null
+++ b/apps/formbricks-com/app/docs/getting-started/quickstart/page.mdx
@@ -0,0 +1,95 @@
+export const meta = {
+ title: "Quickstart",
+ description:
+ "Get started with Formbricks: Choose self-hosted or cloud, create an account, and follow our quickstart guide to set up in-product micro-surveys with ease.",
+};
+
+[Getting Started](#)
+
+# Quickstart
+
+Welcome to Formbricks! In this quickstart guide, we'll walk you through the initial steps to get up and running with our in-product micro-surveys. Choose between self-hosted and cloud options, create an account, and set up the JavaScript widget. Let's dive in!
+
+## Step 1: Choose between self-hosted and cloud
+
+First, you need to decide whether you want to use the self-hosted or cloud version of Formbricks.
+
+- **Self-hosted**: If you prefer to host Formbricks on your own servers, check out the dedicated [Self-hosted Documentation](/docs/self-hosting/deployment) page.
+- **Cloud**: For a hassle-free experience, choose our cloud offering, which takes care of server maintenance and updates for you. [Sign Up now.](https://app.formbricks.com/auth/signup)
+
+## Step 2: Create an account
+
+1. Visit the Formbricks Sign up page.
+2. Enter your email address, choose a password, and click **Sign Up** to create your account. Alternatively you can sign up using your GitHub account.
+
+## Step 3: Switch to the Development Environment
+
+In Formbricks, you can work in different environments to manage your surveys and settings. We recommend using the **Development environment** for your local testing and staging environments to keep your Production environment and it's data clean. To get started, switch to the **Development Environment**:
+
+1. Log in to your Formbricks dashboard.
+2. Click the your profile picture in the top right corner and in the dropdown under your current Environment select **Development**.
+3. Select **Development** from the list.
+
+## Step 4: Set up the JavaScript widget
+
+You can find all the setup instructions as well as a check if your installation was successful in the **Setup Checklist** in the Formbricks settings.
+
+### HTML
+
+Add the following script to the `` tag of your HTML file:
+
+```html
+
+```
+
+Replace your-environment-id with your actual environment ID. You can find your environment ID in the **Setup Checklist** in the Formbricks settings.
+
+### Npm
+
+1. Install the Formbricks package using npm:
+
+```bash
+npm install -s @formbricks/js
+```
+
+2. Import Formbricks and initialize the widget in your main component (e.g., App.tsx or App.js):
+
+```js
+import formbricks from "@formbricks/js";
+
+if (typeof window !== "undefined") {
+ formbricks.init({
+ environmentId: "your-environment-id",
+ apiHost: "https://app.formbricks.com",
+ });
+}
+```
+
+Replace your-environment-id with your actual environment ID. You can find your environment ID in the **Setup Checklist** in the Formbricks settings.
+
+For more detailed guides for different frameworks, check out our [Next.js](/docs/getting-started/nextjs) and [Vue.js](/docs/getting-started/vuejs) guides.
+
+## Step 5: Verify your setup
+
+After setting up the widget, head back to the Formbricks dashboard:
+
+1. Navigate to **Settings** in the top menubar.
+2. Check the **Setup Checklist** to ensure everything is working correctly.
+
+If you see confetti and a green box saying "Receiving data" you've successfully set up Formbricks. You're ready to start creating and customizing your in-product surveys.
diff --git a/apps/formbricks-com/app/docs/getting-started/vuejs/page.mdx b/apps/formbricks-com/app/docs/getting-started/vuejs/page.mdx
new file mode 100644
index 0000000000..7682b2887f
--- /dev/null
+++ b/apps/formbricks-com/app/docs/getting-started/vuejs/page.mdx
@@ -0,0 +1,81 @@
+export const meta = {
+ title: "Setting up Formbricks SDK with Vue.js",
+ description:
+ "Easily integrate Formbricks SDK into your Vue.js app with our guide. Enhance user feedback and improve product experience with customizable in-product micro-surveys.",
+};
+
+[Getting Started](#)
+
+# Setting up Formbricks SDK with Vue.js
+
+In this guide, we will go through the steps to set up the Formbricks SDK in a Vue.js application. This will allow you to create and customize in-product micro-surveys to gather valuable feedback from your users and improve your product experience.
+
+## Introduction
+
+Integrating the Formbricks SDK with Vue.js is a straightforward process. We will make sure the SDK is only loaded and used on the client side, as it's not intended for server-side usage.
+
+## Prerequisites
+
+Before proceeding, ensure you have the following:
+
+1. A Vue.js application set up and ready to go.
+2. A Formbricks account with an `environmentId` and `apiHost` for your application. You can find these in the Setup Checklist in the Settings.
+
+## Installation
+
+To get started, install the Formbricks SDK using your preferred package manager:
+
+```bash
+npm install --save @formbricks/js
+# or
+yarn add @formbricks/js
+# or
+pnpm add @formbricks/js
+```
+
+## Integration
+
+1. Create a new file called \`formbricks.js\` inside the \`src\` folder of your Vue.js application, and add the following code to initialize the Formbricks SDK:
+
+```javascript
+import formbricks from "@formbricks/js";
+
+if (typeof window !== "undefined") {
+ formbricks.init({
+ environmentId: "your-environment-id",
+ apiHost: "your-api-host",
+ });
+}
+
+export default formbricks;
+```
+
+2. In your main.js or main.ts file, import the formbricks.js module:
+
+```javascript
+import formbricks from "@/formbricks";
+```
+
+3. To make sure Formbricks SDK registers every page change in your Vue.js application, add a global navigation guard to your Vue Router configuration:
+
+```javascript
+import Vue from "vue";
+import VueRouter from "vue-router";
+
+Vue.use(VueRouter);
+
+const router = new VueRouter({
+ // Your router configuration here
+});
+
+// Add a global navigation guard
+router.afterEach((to, from) => {
+ if (typeof formbricks !== "undefined") {
+ formbricks.registerRouteChange();
+ }
+});
+```
+
+Now, the Formbricks SDK is set up and ready to use in your Vue.js application. You can start creating and customizing in-product micro-surveys for your users.
+
+For more information on how to use Formbricks SDK, check the rest of the documentation.
diff --git a/apps/formbricks-com/app/docs/groups/page.mdx b/apps/formbricks-com/app/docs/groups/page.mdx
deleted file mode 100644
index e30478703c..0000000000
--- a/apps/formbricks-com/app/docs/groups/page.mdx
+++ /dev/null
@@ -1,448 +0,0 @@
-export const metadata = {
- title: 'Groups',
- description:
- 'On this page, we’ll dive into the different group endpoints you can use to manage groups programmatically.',
-}
-
-# Groups
-
-Groups are where communities live in Protocol — they are a collection of contacts you're talking to all at once. On this page, we'll dive into the different group endpoints you can use to manage groups programmatically. We'll look at how to query, create, update, and delete groups. {{ className: 'lead' }}
-
-## The group model
-
-The group model contains all the information about your groups, including what contacts are in the group and the group's name, description, and avatar.
-
-### Properties
-
-
-
- Unique identifier for the group.
-
-
- The name for the group.
-
-
- The description for the group.
-
-
- The avatar image URL for the group.
-
-
- Unique identifier for the conversation that belongs to the group.
-
-
- An array of contact objects that are members of the group.
-
-
- Timestamp of when the group was created.
-
-
- Timestamp of when the group was archived.
-
-
-
----
-
-## List all groups {{ tag: 'GET', label: '/v1/groups' }}
-
-
-
-
- This endpoint allows you to retrieve a paginated list of all your groups. By default, a maximum of ten groups are shown per page.
-
- ### Optional attributes
-
-
-
- Limit the number of groups returned.
-
-
- Only show groups that are archived when set to `true`.
-
-
-
-
-
-
- This endpoint allows you to create a new group conversation between you and a group of your Protocol contacts.
-
- ### Required attributes
-
-
-
- The name for the group.
-
-
-
- ### Optional attributes
-
-
-
- The description for the group.
-
-
- The avatar image URL for the group.
-
-
- An array of contact objects that are members of the group.
-
-
-
-
-
-
- This endpoint allows you to retrieve a group by providing the group id. Refer to [the list](#the-group-model) at the top of this page to see which properties are included with group objects.
-
-
-
-
- This endpoint allows you to perform an update on a group. Examples of updates are changing the name, description, and avatar or adding and removing contacts from the group.
-
- ### Optional attributes
-
-
-
- The new name for the group.
-
-
- The new description for the group.
-
-
- The new avatar image URL for the group.
-
-
- An array of contact objects that are members of the group.
-
-
- Timestamp of when the group was archived.
-
-
-
-
-
-
- This endpoint allows you to delete groups. Note: This will permanently delete the group, including the messages — archive it instead if you want to be able to restore it later.
-
-
-
-
-
-
- ```bash {{ title: 'cURL' }}
- curl -X DELETE https://api.protocol.chat/v1/groups/L7cGNIBKZiNJ6wqF \
- -H "Authorization: Bearer {token}"
- ```
-
- ```js
- import ApiClient from '@example/protocol-api'
-
- const client = new ApiClient(token)
-
- await client.groups.delete('L7cGNIBKZiNJ6wqF')
- ```
-
- ```python
- from protocol_api import ApiClient
-
- client = ApiClient(token)
-
- client.groups.delete("L7cGNIBKZiNJ6wqF")
- ```
-
- ```php
- $client = new \Protocol\ApiClient($token);
-
- $client->groups->delete('L7cGNIBKZiNJ6wqF');
- ```
-
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/add-new-zap.png b/apps/formbricks-com/app/docs/integrations/zapier/add-new-zap.png
new file mode 100644
index 0000000000..02c3092b9b
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/add-new-zap.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/choose-event.png b/apps/formbricks-com/app/docs/integrations/zapier/choose-event.png
new file mode 100644
index 0000000000..3ecb524db5
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/choose-event.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/connect-with-formbricks-1.png b/apps/formbricks-com/app/docs/integrations/zapier/connect-with-formbricks-1.png
new file mode 100644
index 0000000000..aaa91ad2f6
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/connect-with-formbricks-1.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/connect-with-formbricks-2.png b/apps/formbricks-com/app/docs/integrations/zapier/connect-with-formbricks-2.png
new file mode 100644
index 0000000000..44d943b8f0
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/connect-with-formbricks-2.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/duplicate-survey.png b/apps/formbricks-com/app/docs/integrations/zapier/duplicate-survey.png
new file mode 100644
index 0000000000..4d586acf54
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/duplicate-survey.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/page.mdx b/apps/formbricks-com/app/docs/integrations/zapier/page.mdx
new file mode 100644
index 0000000000..c0e2e5bc99
--- /dev/null
+++ b/apps/formbricks-com/app/docs/integrations/zapier/page.mdx
@@ -0,0 +1,103 @@
+import Image from "next/image";
+
+import AddNewZap from "./add-new-zap.png";
+import ChooseEvent from "./choose-event.png";
+import ConnectWithFB1 from "./connect-with-formbricks-1.png";
+import ConnectWithFB2 from "./connect-with-formbricks-2.png";
+import DuplicateSurvey from "./duplicate-survey.png";
+import SelectSurvey from "./select-survey.png";
+import SlackChannelMsg from "./slack-channel-msg.png";
+import SlackMsg from "./slack-message.png";
+import SubmitTestResponse from "./submit-test-response.png";
+import SuccessConnection from "./success-connected.png";
+import TestSubmission from "./test-submission.png";
+import UpdateQuestionId from "./update-question-id.png";
+import ZapierMessage from "./zapier-message.png";
+
+export const meta = {
+ title: "Zapier Setup",
+ description: "Wire up Formbricks with Zapier and 5000+ other apps",
+};
+
+[Integrations]()
+
+# Zapier Setup
+
+Zapier is a powerful ally. Hook up Formbricks with Zapier and you can send your data to 5000+ other apps. Here is how to do it.
+
+
+ ## Nail down your survey first? {{ class: "text-white" }}
+ Any changes in the survey cause additional work in the Zap. It makes sense to first settle on the survey you
+ want to run and then get to setting up Zapier.
+
+
+## Step 1: Setup your survey incl. `questionId` for every question
+
+When setting up the Zap your life will be easier when you change the `questionId`s of your survey questions. You can only do so **before** you publish your survey.
+
+
+
+_In every question card in the Advanced Settings you find the Question ID field. Update it so that you’ll recognize the response tied to this question._
+
+
+ ## Already published? Duplicate survey {{ class: "text-white" }}
+ You can only update the questionId when the survey was not yet published. Already published it? Just **duplicate
+ it** to update the questionIds.
+
+
+
+## Step 3: Send a test response
+
+In order to set up Zapier you’ll need a test response. This allows you to select the individual values of each response in your Zap. If you have Formbricks running locally and you want to set up an in-app survey, you can use our [Demo App](/docs/contributing/demo) to trigger a survey and submit a response.
+
+
+
+## Step 4: Setup your Zap
+
+Go to [zapier.com](https://zapier.com) and create a new Zap. Search for “Formbricks” to get started:
+
+
+
+Then, choose the event you want to trigger the Zap on:
+
+
+
+## Step 5: Connect Formbricks with Zapier
+
+Now, you have to connect Zapier with Formbricks via an API Key:
+
+
+
+
+Now you need an API key. Please refer to the [API Key Setup](/docs/api/api-key-setup) page to learn how to create one.
+
+Once you copied it in the newly opened Zapier window, you will be connected:
+
+
+
+## Step 6: Select Survey
+
+Next, you can choose from all the surveys you have created in this environment:
+
+
+
+## Step 7: Test your trigger
+
+Once you hit “Test” you will see the three most recent submissions for this survey. If you don’t have any submissions in the survey, submit one to continue setting up your Zap:
+
+
+_Now you're happy that you updated the questionId's_
+
+## Step 8: Set up your Zap
+
+Now you have all the data you need at hand. The next steps depend on what you want to do with it. In this tutorial, we will send submissions to a Slack channel:
+
+
+
+In the action itself we can determine the data and layout of the message. Here, we only choose the submission data. You can also refer to the meta data of the submission and the [attributes](/docs/attributes/why) of the person who submitted the survey.
+
+
+
+We now receive a notifcation in our Slack channel whenever a Churn survey is completed:
+
+
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/select-survey.png b/apps/formbricks-com/app/docs/integrations/zapier/select-survey.png
new file mode 100644
index 0000000000..af489b5c9d
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/select-survey.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/slack-channel-msg.png b/apps/formbricks-com/app/docs/integrations/zapier/slack-channel-msg.png
new file mode 100644
index 0000000000..dccaa6ff91
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/slack-channel-msg.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/slack-message.png b/apps/formbricks-com/app/docs/integrations/zapier/slack-message.png
new file mode 100644
index 0000000000..df0c057762
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/slack-message.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/submit-test-response.png b/apps/formbricks-com/app/docs/integrations/zapier/submit-test-response.png
new file mode 100644
index 0000000000..2476a8f07d
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/submit-test-response.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/success-connected.png b/apps/formbricks-com/app/docs/integrations/zapier/success-connected.png
new file mode 100644
index 0000000000..d8848fa2e7
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/success-connected.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/test-submission.png b/apps/formbricks-com/app/docs/integrations/zapier/test-submission.png
new file mode 100644
index 0000000000..f7ff3cbccb
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/test-submission.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/update-question-id.png b/apps/formbricks-com/app/docs/integrations/zapier/update-question-id.png
new file mode 100644
index 0000000000..21705f00c3
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/update-question-id.png differ
diff --git a/apps/formbricks-com/app/docs/integrations/zapier/zapier-message.png b/apps/formbricks-com/app/docs/integrations/zapier/zapier-message.png
new file mode 100644
index 0000000000..a233212cfa
Binary files /dev/null and b/apps/formbricks-com/app/docs/integrations/zapier/zapier-message.png differ
diff --git a/apps/formbricks-com/app/docs/introduction/how-it-works/page.mdx b/apps/formbricks-com/app/docs/introduction/how-it-works/page.mdx
new file mode 100644
index 0000000000..2f42f7442f
--- /dev/null
+++ b/apps/formbricks-com/app/docs/introduction/how-it-works/page.mdx
@@ -0,0 +1,34 @@
+export const meta = {
+ title: "How Formbricks works",
+ description:
+ "Master in-product micro-surveys with Formbricks: user-friendly form builder, precise targeting, seamless integration, and insightful analytics for SaaS products.",
+};
+
+[Introduction](#)
+
+# How Formbricks works
+
+Formbricks is a powerful platform designed to help you create and manage in-product micro-surveys for SaaS and digital products. Here is an overview:
+
+## Four components
+
+1. **Form Builder**: Create and customize your surveys with a user-friendly, no-code interface.
+2. **Targeting & Triggers**: Define specific user segments and set event-based triggers to display your surveys to the right users at the right time.
+3. **Integration**: Seamlessly integrate Formbricks into your web or mobile application using the provided SDKs or the HTML snippet.
+4. **Analytics & Insights**: Analyze user responses and gain actionable insights to make informed product decisions.
+
+### Form Builder
+
+The Form Builder is where you create and customize your micro-surveys. With its intuitive drag-and-drop interface, you can easily add different question types, set response options, and apply your branding to the survey forms. The Form Builder allows you to preview your survey in real-time, ensuring it looks and feels perfect for your users.
+
+### Targeting & Triggers
+
+Formbricks offers fine-grained user targeting and event-based triggers to help you display your surveys to the most relevant audience. Using the platform, you can define user segments based on attributes and behaviors, and set up triggers to show your surveys at specific moments within your product. This ensures that you're capturing the most accurate and valuable feedback possible.
+
+### Integration
+
+Integrating Formbricks into your web or mobile application is a breeze. With SDKs for popular web frameworks like React, and an HTML snippet for non-framework based websites, you can quickly add Formbricks to your project. The provided code snippets make it easy to initialize the Formbricks widget and configure it to communicate with your backend.
+
+### Analytics & Insights
+
+Formbricks provides powerful analytics and insights to help you understand user responses and make data-driven decisions. The platform aggregates survey results and presents them in an easy-to-understand format, enabling you to identify trends, spot issues, and uncover opportunities for improvement. With Formbricks, you're always one step ahead in understanding your users and optimizing your product experience.
diff --git a/apps/formbricks-com/app/docs/introduction/what-is-formbricks/page.mdx b/apps/formbricks-com/app/docs/introduction/what-is-formbricks/page.mdx
new file mode 100644
index 0000000000..4c075f40b3
--- /dev/null
+++ b/apps/formbricks-com/app/docs/introduction/what-is-formbricks/page.mdx
@@ -0,0 +1,49 @@
+import { GettingStarted } from "@/components/docs/GettingStarted";
+import { BestPractices } from "@/components/docs/BestPractices";
+import { HeroPattern } from "@/components/docs/HeroPattern";
+import { Button } from "@/components/docs/Button";
+
+export const metadata = {
+ title: "Formbricks – Experience Management for B2B SaaS",
+ description:
+ "Natively embed qualitative user research into your B2B SaaS. Leverage Best Practices for user discovery to increase Product-Market Fit",
+};
+
+export const sections = [
+ { title: "Getting Started", id: "getting-started" },
+ { title: "Best Practices", id: "best-practices" },
+];
+
+
+
+# Formbricks – Experience Management for B2B SaaS
+
+Welcome to Formbricks, your go-to solution for in-product micro-surveys that will supercharge your product experience! 🚀 {{ className: 'lead' }}
+
+
+
+
+
+## Why Formbricks? 🤔
+
+Natively embed qualitative user research into your B2B SaaS. Leverage Best Practices for user discovery to increase Product-Market Fit. {{ className: 'lead' }}
+
+- 🎯 **Tailor-made for SaaS & digital products**: Craft stunning, highly configurable surveys that enable better product decisions, deep user segmentation, and personalization.
+- 🌐 **Platform agnostic**: Seamlessly integrate Formbricks surveys into web, mobile, or desktop applications.
+- 📊 **Complete the analytics puzzle**: Answer the "why" behind your product analytics with insightful data analysis and visualization tools.
+- 🧪 **Smart triggering**: Show the right survey at the right time with event-based triggers for accurate research and well-defined priorities.
+- 🎉 **Open-source and self-hosted**: Enjoy full control over your data and infrastructure with our AGPL-licensed solution, and stay tuned for our upcoming cloud version!
+
+
+
+
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/introduction/why-is-it-better/page.mdx b/apps/formbricks-com/app/docs/introduction/why-is-it-better/page.mdx
new file mode 100644
index 0000000000..2df617e3d4
--- /dev/null
+++ b/apps/formbricks-com/app/docs/introduction/why-is-it-better/page.mdx
@@ -0,0 +1,24 @@
+export const meta = {
+ title: "Why is Formbricks better?",
+ description:
+ "The ultimate survey solution for SaaS, offering in-depth micro-surveys, precise targeting, and seamless integrations. Discover the difference today!",
+};
+
+[Introduction](#)
+
+# Why is Formbricks better?
+
+Formbricks outshines other survey tools by specializing in in-product micro-surveys for SaaS and digital products. With Formbricks, you're better equipped to understand user behavior, improve your product, and make data-driven decisions. Let's see how Formbricks compares to generic survey tools.
+
+| Feature | Generic Survey Tool | Formbricks In-Product Surveys |
+| --------------------------- | ------------------- | ----------------------------- |
+| Designed for SaaS | ❌ | ✅ |
+| In-product micro-surveys | ⚠️ (limited) | ✅ |
+| Customizable forms | ✅ | ✅ |
+| Fine-grained user targeting | ❌ | ✅ |
+| Seamless integrations | ⚠️ (limited) | ✅ |
+| Open-source | ❌ | ✅ |
+| Event-based triggers | ❌ | ✅ |
+| User segmentation | ❌ | ✅ |
+
+With Formbricks, you're not just getting another survey tool, but an in-depth, data-driven solution tailor-made for digital products 🎉
diff --git a/apps/formbricks-com/app/docs/layout.tsx b/apps/formbricks-com/app/docs/layout.tsx
index 640bd09196..534d4ec541 100644
--- a/apps/formbricks-com/app/docs/layout.tsx
+++ b/apps/formbricks-com/app/docs/layout.tsx
@@ -1,31 +1,27 @@
-import glob from 'fast-glob'
+import glob from "fast-glob";
-import { Providers } from '@/app/providers'
-import { Layout } from '@/app/docs/_components/Layout'
+import { Providers } from "@/app/providers";
+import { Layout } from "@/components/docs/Layout";
-import { type Metadata } from 'next'
-import { type Section } from '@/app/docs/_components/SectionProvider'
+import { type Metadata } from "next";
+import { type Section } from "@/components/docs/SectionProvider";
export const metadata: Metadata = {
title: {
- template: '%s - Protocol API Reference',
- default: 'Protocol API Reference',
+ template: "Formbricks – Experience Management for B2B SaaS",
+ default: "Official Documentation for Formbricks",
},
-}
+};
-export default async function RootLayout({
- children,
-}: {
- children: React.ReactNode
-}) {
- let pages = await glob('**/*.mdx', { cwd: 'src/app/docs' })
+export default async function RootLayout({ children }: { children: React.ReactNode }) {
+ let pages = await glob("**/*.mdx", { cwd: "src/app/docs" });
let allSectionsEntries = (await Promise.all(
pages.map(async (filename) => [
- '/' + filename.replace(/(^|\/)page\.mdx$/, ''),
+ "/" + filename.replace(/(^|\/)page\.mdx$/, ""),
(await import(`./${filename}`)).sections,
])
- )) as Array<[string, Array]>
- let allSections = Object.fromEntries(allSectionsEntries)
+ )) as Array<[string, Array]>;
+ let allSections = Object.fromEntries(allSectionsEntries);
return (
@@ -33,5 +29,5 @@ export default async function RootLayout({
{children}
- )
+ );
}
diff --git a/apps/formbricks-com/app/docs/link-surveys/data-prefilling/page.mdx b/apps/formbricks-com/app/docs/link-surveys/data-prefilling/page.mdx
new file mode 100644
index 0000000000..5d32fce3ae
--- /dev/null
+++ b/apps/formbricks-com/app/docs/link-surveys/data-prefilling/page.mdx
@@ -0,0 +1,115 @@
+import Image from "next/image";
+
+import QuestionId from "./question-id.png";
+
+export const meta = {
+ title: "Data Prefilling in Link Surveys",
+ description: "Prefill data in your surveys to make it easier for your users to provide feedback.",
+};
+
+[Link Surveys]()
+
+# Data Prefilling in Link Surveys
+
+Data prefilling via the URL allows you to increase conversion rate by prefilling data you already have in a different system.
+
+## Purpose
+
+URL prefilling of data comes in handy when you:
+
+- Have data for some of the respondents, but not all
+- Have data in a different system (e.g. your database) and want to add it to the user profile in Formbricks
+- Want to embed the first question in an email and increase conversion by prefilling the choice
+
+## Quick Example
+
+```txt
+https://app.formbricks.com/s/clin3dxja02k8l80hpwmx4bjy?question_id=5
+```
+
+## How it works
+
+To prefill the first question of a survey, append `?question_id=answer` at the end of the survey URL. The answer has to match the expected type of the question. For example, if the first question is a rating question, the answer has to be a number. If the first question is a single select question, the answer has to be a string.
+
+Please make sure the answer is [URL encoded](https://www.urlencoder.org/).
+
+
+ ## Prefill only the first question {{ class: "text-white" }}
+ Currently, you can only prefill the first question of a link survey.
+
+
+## Where do I find my question Id?
+
+You find the `questionId` in the Advanced Settings at the bottom of each question card in the Survey Editor. As you see, you can update the `questionId` to any string you like. However, once you published your survey, this `questionId` cannot be updated anymore:
+
+
+
+## Examples
+
+Here are a few examples to get you started:
+
+### Rating Question
+
+```txt
+https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?rating_question_id=5
+
+// -> translates to 5 stars / points / emojis
+```
+
+### NPS Question
+
+```txt
+https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?nps_question_id=10
+
+// -> translates to an NPS rating of 10
+```
+
+### Single Select Question (Radio)
+
+```txt
+https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?single_select_question_id=Very%20disappointed
+
+// -> Chooses the option "Very disappointed" in the single select question. The string has to be identical to the option in your question.
+```
+
+### Multi Select Question (Checkbox)
+
+```txt
+https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?multi_select_question_id=Sun%2CPalms%2CBeach
+
+// -> Selects three options "Sun, Palms and Beach" in the multi select question. The strings have to be identical to the options in your question.
+```
+
+### Open Text Question
+
+```txt
+https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?openText_question_id=I%20love%20Formbricks
+
+// -> Adds "I love Formbricks" as the answer to the open text question
+```
+
+### CTA Question
+
+```txt
+https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?cta_question_id=clicked
+
+// -> Adds "clicked" as the answer to the CTA question. Alternatively, you can set it to "dismissed" to skip the question.
+```
+
+## Validation
+
+Make sure that the answer in the URL matches the expected type for the first question.
+
+The URL validation works as follows:
+
+- For Rating or NPS questions, the response is parsed as a number and verified if it's accepted by the schema.
+- For CTA type questions, the valid values are "clicked" (main CTA) and "dismissed" (skip CTA).
+- For Consent type questions, the valid values are "accepted" (consent given) and "dismissed" (consent not given).
+- All other question types are strings.
+
+### You’re good to go! 🎉
diff --git a/apps/formbricks-com/app/docs/link-surveys/data-prefilling/question-id.png b/apps/formbricks-com/app/docs/link-surveys/data-prefilling/question-id.png
new file mode 100644
index 0000000000..83aa7e647e
Binary files /dev/null and b/apps/formbricks-com/app/docs/link-surveys/data-prefilling/question-id.png differ
diff --git a/apps/formbricks-com/app/docs/link-surveys/user-identification/page.mdx b/apps/formbricks-com/app/docs/link-surveys/user-identification/page.mdx
new file mode 100644
index 0000000000..3ba1854842
--- /dev/null
+++ b/apps/formbricks-com/app/docs/link-surveys/user-identification/page.mdx
@@ -0,0 +1,56 @@
+import Image from "next/image";
+
+import PeopleView from "./people-view.png";
+
+export const meta = {
+ title: "User Identification in Link Surveys",
+ description:
+ "Identify users in link surveys via URL parameter. Connect responses to existing users in Formbricks.",
+};
+
+[Link Surveys]()
+
+# User Identification in Link Surveys
+
+Identifying users in link features lets you connect responses from link surveys with existing users in your Formbricks database.
+
+## Purpose
+
+Identifying users in link surveys comes in handy when you:
+
+- Want to send out link surveys to existing users in your database
+- Want to connect responses from link surveys with existing users in your database
+- Want to gather data and later connect it to a user who has not signed up yet
+
+## Quick Example
+
+```txt
+https://app.formbricks.com/s/clin3dxja02k8l80hpwmx4bjy?userId=ABC123
+```
+
+## How it works
+
+To link a response to a user in your Formbricks database, you can pass your internal user Id as a URL parameter.
+
+## Where do I find my userId?
+
+The `userId` we are refering to is the `userId` of your own system. For example, a user signs up to your app and gets the Id `ABC123` assigned then this is the Id you pass along in the URL parameter.
+
+This allows you to connect the response to the user profile of this specific in the Formbricks database. You can then use the response data to create segments for further surveying or invite them to an interview, etc.
+
+## getOrCreateUser - how it works exactly
+
+By default, respondents of link surveys are **not** recorded and displayed in the People view. This would lead to your People view to be spammend with unidentified people.
+
+If you add the `userId` URL parameter a Person will be created, if there is no existing person in your database with a matching `userId`.
+
+**Case 1:** User with userId `ABC111` exists, the response from the link survey will be added to this users profile.
+
+**Case 2:** User with userId `ABC222` does not yet exists, so it is created with the response from the link survey connected to this user.
+
+
diff --git a/apps/formbricks-com/app/docs/link-surveys/user-identification/people-view.png b/apps/formbricks-com/app/docs/link-surveys/user-identification/people-view.png
new file mode 100644
index 0000000000..502d520dcf
Binary files /dev/null and b/apps/formbricks-com/app/docs/link-surveys/user-identification/people-view.png differ
diff --git a/apps/formbricks-com/app/docs/messages/page.mdx b/apps/formbricks-com/app/docs/messages/page.mdx
deleted file mode 100644
index e3cbca0a24..0000000000
--- a/apps/formbricks-com/app/docs/messages/page.mdx
+++ /dev/null
@@ -1,441 +0,0 @@
-export const metadata = {
- title: 'Messages',
- description:
- 'On this page, we’ll dive into the different message endpoints you can use to manage messages programmatically.',
-}
-
-# Messages
-
-Messages are what conversations are made of in Protocol — they are the basic building blocks of your conversations with your Protocol contacts. On this page, we'll dive into the different message endpoints you can use to manage messages programmatically. We'll look at how to query, send, update, and delete messages. {{ className: 'lead' }}
-
-## The message model
-
-The message model contains all the information about the messages and attachments you send to your contacts and groups, including how your contacts have reacted to them.
-
-### Properties
-
-
-
- Unique identifier for the message.
-
-
- Unique identifier for the conversation the message belongs to.
-
-
- The contact object for the contact who sent the message.
-
-
- The message content.
-
-
- An array of reaction objects associated with the message.
-
-
- An array of attachment objects associated with the message.
-
-
- Timestamp of when the message was read.
-
-
- Timestamp of when the message was created.
-
-
- Timestamp of when the message was last updated.
-
-
-
----
-
-## List all messages {{ tag: 'GET', label: '/v1/messages' }}
-
-
-
-
- This endpoint allows you to retrieve a paginated list of all your messages (in a conversation if a conversation id is provided). By default, a maximum of ten messages are shown per page.
-
- ### Optional attributes
-
-
-
- Limit to messages from a given conversation.
-
-
- Limit the number of messages returned.
-
-
-
-
-
-
- This endpoint allows you to send a new message to one of your conversations.
-
- ### Required attributes
-
-
-
- Unique identifier for the conversation the message belongs to.
-
-
- The message content.
-
-
-
- ### Optional attributes
-
-
-
- An array of attachment objects associated with the message.
-
-
-
-
-
-
- This endpoint allows you to retrieve a message by providing the message id. Refer to [the list](#the-message-model) at the top of this page to see which properties are included with message objects.
-
-
-
-
- This endpoint allows you to perform an update on a message. Examples of updates are adding a reaction, editing the message, or adding an attachment.
-
- ### Optional attributes
-
-
-
- The message content.
-
-
- An array of reaction objects associated with the message.
-
-
- An array of attachment objects associated with the message.
-
-
-
-
-
-
- This endpoint allows you to delete messages from your conversations. Note: This will permanently delete the message.
-
-
-
-
-
-
- ```bash {{ title: 'cURL' }}
- curl -X DELETE https://api.protocol.chat/v1/messages/SIuAFUNKdSYHZF2w \
- -H "Authorization: Bearer {token}"
- ```
-
- ```js
- import ApiClient from '@example/protocol-api'
-
- const client = new ApiClient(token)
-
- await client.messages.delete('SIuAFUNKdSYHZF2w')
- ```
-
- ```python
- from protocol_api import ApiClient
-
- client = ApiClient(token)
-
- client.messages.delete("SIuAFUNKdSYHZF2w")
- ```
-
- ```php
- $client = new \Protocol\ApiClient($token);
-
- $client->messages->delete('SIuAFUNKdSYHZF2w');
- ```
-
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/page.mdx b/apps/formbricks-com/app/docs/page.mdx
deleted file mode 100644
index 2871f6a3f6..0000000000
--- a/apps/formbricks-com/app/docs/page.mdx
+++ /dev/null
@@ -1,42 +0,0 @@
-import { Guides } from '@/app/docs/_components/Guides'
-import { Resources } from '@/app/docs/_components/Resources'
-import { HeroPattern } from '@/app/docs/_components/HeroPattern'
-
-export const metadata = {
- title: 'API Documentation',
- description:
- 'Learn everything there is to know about the Protocol API and integrate Protocol into your product.',
-}
-
-export const sections = [
- { title: 'Guides', id: 'guides' },
- { title: 'Resources', id: 'resources' },
-]
-
-
-
-# API Documentation
-
-Use the Protocol API to access contacts, conversations, group messages, and more and seamlessly integrate your product into the workflows of dozens of devoted Protocol users. {{ className: 'lead' }}
-
-
-
-
-
-
-## Getting started {{ anchor: false }}
-
-To get started, create a new application in your [developer settings](#), then read about how to make requests for the resources you need to access using our HTTP APIs or dedicated client SDKs. When your integration is ready to go live, publish it to our [integrations directory](#) to reach the Protocol community. {{ className: 'lead' }}
-
-
-
-
-
-
-
-
diff --git a/apps/formbricks-com/app/docs/pagination/page.mdx b/apps/formbricks-com/app/docs/pagination/page.mdx
deleted file mode 100644
index 8bec705237..0000000000
--- a/apps/formbricks-com/app/docs/pagination/page.mdx
+++ /dev/null
@@ -1,63 +0,0 @@
-export const metadata = {
- title: 'Pagination',
- description:
- 'In this guide, we will look at how to work with paginated responses when querying the Protocol API',
-}
-
-# Pagination
-
-In this guide, we will look at how to work with paginated responses when querying the Protocol API. By default, all responses limit results to ten. However, you can go as high as 100 by adding a `limit` parameter to your requests. If you are using one of the official Protocol API client libraries, you don't need to worry about pagination, as it's all being taken care of behind the scenes. {{ className: 'lead' }}
-
-When an API response returns a list of objects, no matter the amount, pagination is supported. In paginated responses, objects are nested in a `data` attribute and have a `has_more` attribute that indicates whether you have reached the end of the last page. You can use the `starting_after` and `endding_before` query parameters to browse pages.
-
-## Example using cursors
-
-
-
-
- In this example, we request the page that starts after the conversation with id `s4WycXedwhQrEFuM`. As a result, we get a list of three conversations and can tell by the `has_more` attribute that we have reached the end of the resultset.
-
-
-
- The last ID on the page you're currently on when you want to fetch the next page.
-
-
- The first ID on the page you're currently on when you want to fetch the previous page.
-
-
- Limit the number of items returned.
-
-
-
-
-
-
- ```bash {{ title: 'Manual pagination using cURL' }}
- curl -G https://api.protocol.chat/v1/conversations \
- -H "Authorization: Bearer {token}" \
- -d starting_after="s4WycXedwhQrEFuM" \
- -d limit=10
- ```
-
- ```json {{ title: 'Paginated response' }}
- {
- "has_more": false,
- "data": [
- {
- "id": "WAz8eIbvDR60rouK",
- // ...
- },
- {
- "id": "hSIhXBhNe8X1d8Et"
- // ...
- },
- {
- "id": "fbwYwpi9C2ybt6Yb"
- // ...
- }
- ]
- }
- ```
-
-
-
diff --git a/apps/formbricks-com/app/docs/quickstart/page.mdx b/apps/formbricks-com/app/docs/quickstart/page.mdx
deleted file mode 100644
index d3a46bcf99..0000000000
--- a/apps/formbricks-com/app/docs/quickstart/page.mdx
+++ /dev/null
@@ -1,104 +0,0 @@
-export const metadata = {
- title: 'Quickstart',
- description:
- 'This guide will get you all set up and ready to use the Protocol API. We’ll cover how to get started an API client and how to make your first API request.',
-}
-
-# Quickstart
-
-This guide will get you all set up and ready to use the Protocol API. We'll cover how to get started using one of our API clients and how to make your first API request. We'll also look at where to go next to find all the information you need to take full advantage of our powerful REST API. {{ className: 'lead' }}
-
-
- Before you can make requests to the Protocol API, you will need to grab your
- API key from your dashboard. You find it under [Settings » API](#).
-
-
-## Choose your client
-
-Before making your first API request, you need to pick which API client you will use. In addition to good ol' cURL HTTP requests, Protocol offers clients for JavaScript, Python, and PHP. In the following example, you can see how to install each client.
-
-
-
-```bash {{ title: 'cURL' }}
-# cURL is most likely already installed on your machine
-curl --version
-```
-
-```bash {{ language: 'js' }}
-# Install the Protocol JavaScript SDK
-npm install @example/protocol-api --save
-```
-
-```bash {{ language: 'python' }}
-# Install the Protocol Python SDK
-pip install protocol_api
-```
-
-```bash {{ language: 'php' }}
-# Install the Protocol PHP SDK
-composer require protocol/sdk
-```
-
-
-
-
-
-
-
-## Making your first API request
-
-After picking your preferred client, you are ready to make your first call to the Protocol API. Below, you can see how to send a GET request to the Conversations endpoint to get a list of all your conversations. In the cURL example, results are limited to ten conversations, the default page length for each client.
-
-
-
-```bash {{ title: 'cURL' }}
-curl -G https://api.protocol.chat/v1/conversations \
- -H "Authorization: Bearer {token}" \
- -d limit=10
-```
-
-```js
-import ApiClient from '@example/protocol-api'
-
-const client = new ApiClient(token)
-
-await client.conversations.list()
-```
-
-```python
-from protocol_api import ApiClient
-
-client = ApiClient(token)
-
-client.conversations.list()
-```
-
-```php
-$client = new \Protocol\ApiClient($token);
-
-$client->conversations->list();
-```
-
-
-
-
-
-
-
-## What's next?
-
-Great, you're now set up with an API client and have made your first request to the API. Here are a few links that might be handy as you venture further into the Protocol API:
-
-- [Grab your API key from the Protocol dashboard](#)
-- [Check out the Conversations endpoint](/conversations)
-- [Learn about the different error messages in Protocol](/errors)
diff --git a/apps/formbricks-com/app/docs/sdks/page.mdx b/apps/formbricks-com/app/docs/sdks/page.mdx
deleted file mode 100644
index df01636524..0000000000
--- a/apps/formbricks-com/app/docs/sdks/page.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Libraries } from '@/app/docs/_components/Libraries'
-
-export const metadata = {
- title: 'Protocol SDKs',
- description:
- 'Protocol offers fine-tuned JavaScript, Ruby, PHP, Python, and Go libraries to make your life easier and give you the best experience when consuming the API.',
-}
-
-export const sections = [
- { title: 'Official libraries', id: 'official-libraries' },
-]
-
-# Protocol SDKs
-
-The recommended way to interact with the Protocol API is by using one of our official SDKs. Today, Protocol offers fine-tuned JavaScript, Ruby, PHP, Python, and Go libraries to make your life easier and give you the best experience when consuming the API. {{ className: 'lead' }}
-
-
diff --git a/apps/formbricks-com/app/docs/self-hosting/deployment/page.mdx b/apps/formbricks-com/app/docs/self-hosting/deployment/page.mdx
new file mode 100644
index 0000000000..ed655be4bf
--- /dev/null
+++ b/apps/formbricks-com/app/docs/self-hosting/deployment/page.mdx
@@ -0,0 +1,209 @@
+export const meta = {
+ title: "Deploying Formbricks to production",
+ description:
+ "Utilize Docker-Compose for easy deployment on your machine. Clone the repo, configure settings, and build the image to access the app on localhost.",
+};
+
+[Self-hosting]()
+
+# Deploying Formbricks to production
+
+At Formbricks, we understand that different users have different needs, and we strive to cater to a wide variety of situations. This is why we provide three ways of running our application:
+
+1. **Production Instance Setup with Shell Script on Ubuntu**: If you want to quickly set up a production instance of Formbricks on a server running Ubuntu, we've got you covered! This method utilizes a convenient shell script that takes care of everything, including Docker, Postgres DB, and SSL certificate configuration. The shell script will automatically install all the required dependencies and configure your server, making the process a breeze.
+
+2. **Fast Setup with a Pre-built Docker Image:** This method is designed for those who want to quickly set up and start using Formbricks without getting into the technicalities of Docker or the build process. When you choose this method, you're using an image that we've already built for you. The pre-built image is ready-to-run, and it only requires minimal configuration on your part. This approach is perfect for getting a functional instance of Formbricks up and running with minimal hassle. It's as easy as downloading the Docker image and firing up the container.
+
+3. **Manual Setup by Building the Docker Image from Source:** This approach provides the flexibility to configure every aspect of your Formbricks instance, including environment variables that need to be set at build time. While we don't recommend changing the source code of Formbricks, this method allows you to set your own configuration that might be necessary for specific deployment needs. Keep in mind that this method requires a more in-depth understanding of Docker and the build process. However, the trade-off is the additional control and flexibility you gain, making it worth considering if you're a more advanced user or have very specific configuration needs.
+
+Please note that regardless of the method you choose, Formbricks is designed to be easy-to-use and flexible. So choose the method that best fits your comfort level and requirements, and start leveraging the power of Formbricks today!
+
+---
+
+## (Most users: One-click Ubuntu setup) Running the Shell Script
+
+This is the quickest way to get Formbricks up and running on an Ubuntu server. The shell script will automatically install all the required dependencies and configure your server, making the process a breeze.
+
+### Requirements
+
+Before you proceed, make sure you have the following:
+
+- A Linux Ubuntu Virtual Machine deployed with SSH access.
+
+- An A record set up to connect a custom domain to your instance. Formbricks will automatically create an SSL certificate for your domain using Let's Encrypt.
+
+## Single Command Setup
+
+Copy and paste the following command into your terminal:
+
+```bash
+/bin/sh -c "$(curl -fsSL https://raw.githubusercontent.com/formbricks/formbricks/main/docker/production.sh)"
+```
+
+The script will prompt you for the following information:
+
+1. **Overwriting Docker GPG Keys**: If Docker GPG keys already exist, the script will ask if you want to overwrite them.
+
+2. **Email Address**: Provide your email address for SSL certificate registration with Let's Encrypt.
+
+3. **Domain Name**: Enter the domain name that Traefik will use to create the SSL certificate and forward requests to Formbricks.
+
+That's it! After running the command and providing the required information, visit the domain name you entered, and you should see the Formbricks home wizard!
+
+## (Manual Deployment) Running the pre-built Docker Image
+
+### Requirements
+
+Ensure `docker` & `docker compose` are installed on your server/system. Both are typically included with Docker utilities, like Docker Desktop and Rancher Desktop.
+
+**Note**: `docker compose` without the hyphen is now the primary method of using docker-compose, according to the Docker documentation.
+
+This is suitable for those who are testing Formbricks or running it with minimal to no modifications. For this we use the [public Docker image](https://hub.docker.com/r/formbricks/formbricks) and a simple docker-compose file.
+
+1. **Create a New Directory for Formbricks**
+
+ Open a terminal and create a new directory for Formbricks, then navigate into this new directory:
+
+ ```bash
+ mkdir formbricks-quickstart && cd formbricks-quickstart
+ ```
+
+2. **Download the Docker-Compose File**
+
+ Download the docker-compose file directly from the Formbricks repository:
+
+ ```bash
+ curl -o docker-compose.yml https://raw.githubusercontent.com/formbricks/formbricks/main/docker/docker-compose.yml
+ ```
+
+3. **Generate NextAuth Secret**
+
+ Next, you need to generate a NextAuth secret. This will be used for session signing and encryption. The `sed` command below generates a random string using `openssl`, then replaces the `NEXTAUTH_SECRET:` placeholder in the `docker-compose.yml` file with this generated secret:
+
+ ```bash
+ sed -i "/NEXTAUTH_SECRET:$/s/NEXTAUTH_SECRET:.\*/NEXTAUTH_SECRET: $(openssl rand -base64 32)/" docker-compose.yml
+ ```
+
+4. **Start the Docker Setup**
+
+ You're now ready to start the Formbricks Docker setup. The following command will start Formbricks together with a postgreSQL database using Docker Compose:
+
+ ```bash
+ docker compose up -d
+ ```
+
+ The `-d` flag will run the containers in detached mode, meaning they'll run in the background.
+
+5. **Visit Formbricks in Your Browser**
+
+ After starting the Docker setup, visit http://localhost:3000 in your browser to interact with the Formbricks application. The first time you access this page, you'll be greeted by a setup wizard. Follow the prompts to define your first user and get started.
+
+## Updating Formbricks
+
+1. Stop the Formbricks stack
+
+ ```bash
+ docker compose down
+ ```
+
+2. Pull the latest changes
+
+ ```bash
+ docker compose pull
+ ```
+
+3. Update env vars as necessary.
+4. Re-start the Formbricks stack
+
+ ```bash
+ docker compose up -d
+ ```
+
+## (Advanced users) Build and Run Formbricks
+
+### Requirements
+
+Ensure `docker` & `docker compose` are installed on your server/system. Both are typically included with Docker utilities, like Docker Desktop and Rancher Desktop.
+
+**Note**: `docker compose` without the hyphen is now the primary method of using docker-compose, according to the Docker documentation.
+
+1. Clone the repository:
+
+ ```bash
+ git clone https://github.com/formbricks/formbricks.git && cd formbricks
+ ```
+
+2. Modify the `.env.docker` file as required by your setup. This file comes with a basic setup and Formbricks works without making any changes to the file. To enable email sending functionality you need to configure the SMTP settings. If you configured your email credentials, you can also comment the following lines to enable email verification (`# NEXT_PUBLIC_EMAIL_VERIFICATION_DISABLED=1`) and password reset (`# NEXT_PUBLIC_PASSWORD_RESET_DISABLED=1`)
+
+ Note: All environment variables starting with `NEXT_PUBLIC_` are used at build time. When you change environment variables later, you need to rebuild the image with `docker compose build` for the changes to take effect.
+
+3. Finally start the docker compose process to build and spin up the Formbricks container as well as the PostgreSQL database.
+
+ ```bash
+ docker compose up -d
+ # (use docker-compose if you are on an older docker version)
+ ```
+
+ You can now access the app on [http://localhost:3000](http://localhost:3000). You will be automatically redirected to the login. To use your local installation of Formbricks, create a new account.
+
+Certainly, here is the reformatted version for Formbricks environment variables.
+
+### Important Run-time Variables
+
+These variables must also be provided at runtime.
+
+| Variable | Description | Required | Default |
+| --------------- | --------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------- |
+| WEBAPP_URL | Base URL of the site. | required | `http://localhost:3000` |
+| DATABASE_URL | Database URL with credentials. | required | `postgresql://postgres:postgres@postgres:5432/formbricks?schema=public` |
+| NEXTAUTH_SECRET | Secret for NextAuth, used for session signing and encryption. | required | (Generated by the user) |
+| NEXTAUTH_URL | Location of the auth server. By default, this is the Formbricks docker instance itself. | required | `http://localhost:3000` |
+
+### Build-time Variables
+
+These variables must be provided at the time of the docker build and can be provided by updating the `.env` file.
+
+| Variable | Description | Required | Default |
+| --------------------------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------------- | ----------------------- |
+| NEXT_PUBLIC_WEBAPP_URL | Base URL injected into static files. | required | `http://localhost:3000` |
+| PRISMA_GENERATE_DATAPROXY | Enables a dedicated connection pool for Prisma using Prisma Data Proxy. Uncomment to enable. | optional | |
+| NEXT_PUBLIC_EMAIL_VERIFICATION_DISABLED | Disables email verification if set to `1`. | optional | |
+| NEXT_PUBLIC_PASSWORD_RESET_DISABLED | Disables password reset functionality if set to `1`. | optional | |
+| NEXT_PUBLIC_SIGNUP_DISABLED | Disables the ability for new users to create an account if set to `1`. | optional | |
+| NEXT_PUBLIC_INVITE_DISABLED | Disables the ability for invited users to create an account if set to `1`. | optional | |
+| NEXT_PUBLIC_PRIVACY_URL | URL for privacy policy. | optional | |
+| NEXT_PUBLIC_TERMS_URL | URL for terms of service. | optional | |
+| NEXT_PUBLIC_IMPRINT_URL | URL for imprint. | optional | |
+| SENTRY_IGNORE_API_RESOLUTION_ERROR | Disables Sentry warning if set to `1`. | optional | |
+| NEXT_PUBLIC_SENTRY_DSN | DSN for Sentry error tracking. | optional | |
+| NEXT_PUBLIC_GITHUB_AUTH_ENABLED | Enables GitHub login if set to `1`. | optional | |
+| GITHUB_ID | Client ID for GitHub. | optional (required if GitHub auth is enabled) | |
+| GITHUB_SECRET | Secret for GitHub. | optional (required if GitHub auth is enabled) | |
+| NEXT_PUBLIC_GOOGLE_AUTH_ENABLED | Enables Google login if set to `1`. | optional | |
+| GOOGLE_CLIENT_ID | Client ID for Google. | optional (required if Google auth is enabled) | |
+| GOOGLE_CLIENT_SECRET | Secret for Google. | optional (required if Google auth is enabled) | |
+| CRON_SECRET | Secret for running cron jobs. | optional | |
+
+Please refer to the [Formbricks Instructions](https://github.com/formbricks/formbricks) for more details on generating these variables.
+
+## Debugging
+
+If you encounter any issues, you can check the logs of the container with:
+
+```bash
+docker compose logs -f
+```
+
+You can close the logs again with `CTRL + C`.
+
+## Troubleshooting for the Shell Script Setup
+
+If you encounter any issues, consider the following steps:
+
+- **Inbound Rules**: Make sure you have added inbound rules for Port 80 and 443 in your VM's Security Group.
+
+- **A Record**: Verify that you have set up an A record for your domain, pointing to your VM's IP address.
+
+- **Check Docker Instances**: Run `docker ps` to check the status of the Docker instances.
+
+- **Check Formbricks Logs**: Run `cd formbricks && docker compose logs` to check the logs of the Formbricks stack.
diff --git a/apps/formbricks-com/app/docs/webhook-api/create-webhook/page.mdx b/apps/formbricks-com/app/docs/webhook-api/create-webhook/page.mdx
new file mode 100644
index 0000000000..bbe21b8545
--- /dev/null
+++ b/apps/formbricks-com/app/docs/webhook-api/create-webhook/page.mdx
@@ -0,0 +1,108 @@
+export const meta = {
+ title: "API: Create webhook",
+ description: "Learn how to create a new webhook via API.",
+};
+
+[Webhook API]()
+
+# API: Create webhook
+
+## Create a new Webhook {{ tag: 'POST', label: '/api/v1/webhooks' }}
+
+Add a webhook to your product.
+
+
+
+
+ ### Mandatory Headers
+
+
+
+ Your Formbricks API key.
+
+
+
+ ### Request Body Parameters
+
+
+
+ The URL where the webhook will send data to.
+
+
+ List of events that will trigger the webhook.
+
+
+ List of survey IDs that will trigger the webhook. If not provided, the webhook will be triggered for all surveys.
+
+
+
+| field name | required | default | description |
+| ---------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
+| url | yes | - | The endpoint that the webhook will send data to |
+| trigger | yes | - | The event that will trigger the webhook ("responseCreated" or "responseUpdated" or "responseFinished") |
+| surveyIds | no | - | List of survey IDs that will trigger the webhook. If not provided, the webhook will be triggered for all surveys. |
+
+
+
+
+ ### Mandatory Headers
+
+
+
+ Your Formbricks API key.
+
+
+
+
+
+
+
+
+ ```bash {{ title: 'cURL' }}
+ curl --location --request DELETE 'https://app.formbricks.com/api/v1/webhooks/[webhookId]' \
+ --header 'x-api-key: '
+ ```
+
+
+
+
+
+ ```json {{ title: '200 Success' }}
+ {
+ "data": {
+ "id": "cliu167rk000019zfhbo68bar",
+ "createdAt": "2023-06-13T08:38:02.960Z",
+ "updatedAt": "2023-06-13T08:38:02.960Z",
+ "url": "https://mysystem.com/myendpoint",
+ "environmentId": "clisypjy4000319t4imm289uo",
+ "triggers": ["responseFinished"]
+ }
+ }
+ ```
+
+ ```json {{ title: '401 Not Authenticated' }}
+ {
+ "code": "not_authenticated",
+ "message": "Not authenticated",
+ "details": {
+ "x-Api-Key": "Header not provided or API Key invalid"
+ }
+ }
+ ```
+
+ ```json {{ title: '404 Not Found' }}
+ {
+ "code": "not_found",
+ "message": "Webhook not found.",
+ "details": {
+ "webhookId": "The requested webhook does not exist."
+ }
+ }
+ ```
+
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/webhook-api/get-webhook/page.mdx b/apps/formbricks-com/app/docs/webhook-api/get-webhook/page.mdx
new file mode 100644
index 0000000000..ba8cb13221
--- /dev/null
+++ b/apps/formbricks-com/app/docs/webhook-api/get-webhook/page.mdx
@@ -0,0 +1,67 @@
+export const meta = {
+ title: "API: Get Webhook",
+ description: "Learn how to retrieve a specific webhook by its ID via API.",
+};
+
+[Webhook API]()
+
+# API: Get Webhook
+
+## Retrieve a specific webhook by its ID {{ tag: 'GET', label: '/api/v1/webhooks/[webhookId]' }}
+
+
+
+
+ ### Mandatory Headers
+
+
+
+ Your Formbricks API key.
+
+
+
+
+
+
+
+
+ ```bash {{ title: 'cURL' }}
+ curl --location \
+ 'https://app.formbricks.com/api/v1/webhooks/[webhookId]' \
+ --header \
+ 'x-api-key: '
+ ```
+
+
+
+
+
+ ```json {{ title: '200 Success' }}
+ {
+ "data": {
+ "id": "cliu167rk000019zfhbo68bar",
+ "createdAt": "2023-06-13T08:38:02.960Z",
+ "updatedAt": "2023-06-13T08:38:02.960Z",
+ "url": "https://mysystem.com/myendpoint",
+ "environmentId": "clisypjy4000319t4imm289uo",
+ "triggers": [
+ "responseFinished"
+ ]
+ }
+ }
+ ```
+
+ ```json {{ title: '401 Not Authenticated' }}
+ {
+ "code": "not_authenticated",
+ "message": "Not authenticated",
+ "details": {
+ "x-Api-Key": "Header not provided or API Key invalid"
+ }
+ }
+ ```
+
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/webhook-api/list-webhooks/page.mdx b/apps/formbricks-com/app/docs/webhook-api/list-webhooks/page.mdx
new file mode 100644
index 0000000000..d737b8b6d3
--- /dev/null
+++ b/apps/formbricks-com/app/docs/webhook-api/list-webhooks/page.mdx
@@ -0,0 +1,71 @@
+export const meta = {
+ title: "API: List Webhooks",
+ description: "Learn how to retrieve a list of all webhooks via API.",
+};
+
+[Webhook API]()
+
+# API: List Webhooks
+
+## Retrieve a list of all webhooks {{ tag: 'GET', label: '/api/v1/webhooks' }}
+
+
+
+
+ Learn how to retrieve a list of all webhooks via API.
+
+ ### Mandatory Headers
+
+
+
+ Your Formbricks API key.
+
+
+
+
+
+
+
+
+ ```bash {{ title: 'cURL' }}
+ curl --location \
+ 'https://app.formbricks.com/api/v1/webhooks' \
+ --header \
+ 'x-api-key: '
+ ```
+
+
+
+
+
+ ```json {{ title: '200 Success' }}
+ {
+ "data": [
+ {
+ "id": "cliu1kdza000219zftad4ip6c",
+ "createdAt": "2023-06-13T08:49:04.198Z",
+ "updatedAt": "2023-06-13T08:49:04.198Z",
+ "url": "https://mysystem.com/myendpoint",
+ "environmentId": "clisypjy4000319t4imm289uo",
+ "triggers": [
+ "responseFinished"
+ ]
+ }
+ ]
+ }
+ ```
+
+ ```json {{ title: '401 Not Authenticated' }}
+ {
+ "code": "not_authenticated",
+ "message": "Not authenticated",
+ "details": {
+ "x-Api-Key": "Header not provided or API Key invalid"
+ }
+ }
+ ```
+
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/webhook-api/overview/page.mdx b/apps/formbricks-com/app/docs/webhook-api/overview/page.mdx
new file mode 100644
index 0000000000..6fecfa222a
--- /dev/null
+++ b/apps/formbricks-com/app/docs/webhook-api/overview/page.mdx
@@ -0,0 +1,25 @@
+export const meta = {
+ title: "Webhook API Overview",
+ description: "Learn how to use the Formbricks Webhook API.",
+};
+
+[Webhook API]()
+
+# Webhook API Overview
+
+Formbricks' Webhook API offers a powerful interface for interacting with webhooks. Webhooks in Formbricks allow you to receive real-time HTTP notifications of changes to specific objects in the Formbricks environment.
+
+Before you start managing webhooks, you need to create an API key. This will be used for authorization when making requests to the Webhook API. Please see the [API key setup page](/docs/api/api-key-setup) for more details on how to create and manage your API keys.
+
+The behavior of the webhooks is determined by their trigger settings. The trigger determines which updates the webhook sends. Current available triggers include "responseCreated", "responseUpdated", and "responseFinished". This allows you to customize your webhooks to only send notifications for the events that are relevant to your application.
+
+Webhooks are tied to a specific Formbricks environment. Once set, a webhook will receive updates from all surveys within this environment. This makes it easy to manage your data flow and ensure that all relevant updates are caught by the webhook.
+
+Our API has several REST endpoints enabling you to manage these webhooks, providing a great deal of flexibility:
+
+1. **List Webhooks:** Retrieve a list of all existing webhooks.
+2. **Create a New Webhook:** Add a new webhook to your system.
+3. **Get a Specific Webhook:** Query the details of a specific webhook using its unique ID.
+4. **Delete a Webhook:** Remove an existing webhook.
+
+These APIs are designed to facilitate seamless integration of Formbricks with third-party systems. By making use of our webhook API, you can automate the process of sending data to these systems whenever significant events occur within your Formbricks environment.
diff --git a/apps/formbricks-com/app/docs/webhook-api/webhook-payload/page.mdx b/apps/formbricks-com/app/docs/webhook-api/webhook-payload/page.mdx
new file mode 100644
index 0000000000..fc1474b3d5
--- /dev/null
+++ b/apps/formbricks-com/app/docs/webhook-api/webhook-payload/page.mdx
@@ -0,0 +1,79 @@
+export const meta = {
+ title: "Webhook Payload",
+ description: "Learn how to handle the Formbricks API payload.",
+};
+
+[Webhook API]()
+
+# Webhook Payload
+
+This documentation helps understand the payload structure that will be received when the webhook is triggered in Formbricks.
+
+
+
+
+| Variable | Type | Description |
+| --------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
+| webhookId | String | Webhook's Id |
+| event | String | The name of the trigger event [responseCreated, responseUpdated, responseFinished] |
+| data | Object | Contains the details of the newly created response. |
+| data.id | String | Formbricks Response ID. |
+| data.createdAt | String | The timestamp when the response was created. |
+| data.updatedAt | String | The timestamp when the response was last updated. |
+| data.surveyId | String | The identifier of the survey associated with this response. |
+| data.finished | Boolean | A boolean value indicating whether the survey response is marked as finished. |
+| data.data | Object | An object containing the response data, where keys are question identifiers, and values are the corresponding answers given by the respondent. |
+| data.meta | Object | Additional metadata related to the response, such as the user's operating system and browser information. |
+| data.personAttributes | Object | An object with attributes related to the respondent, such as their email and a user ID (if available). |
+| data.person | Object | Information about the respondent, including their unique id, attributes, and creation/update timestamps. |
+| data.notes | Array | An array of notes associated with the response (if any). |
+| data.tags | Array | An array of tags assigned to the response (if any). |
+
+
+
+
+ ## An example webhook payload
+
+
+
+ ```json
+ {
+ "webhookId": "cljwxvjos0003qhnvj2jg4k5i",
+ "event": "responseCreated",
+ "data": {
+ "id": "cljwy2m8r0001qhclco1godnu",
+ "createdAt": "2023-07-10T14:14:17.115Z",
+ "updatedAt": "2023-07-10T14:14:17.115Z",
+ "surveyId": "cljsf3d7a000019cv9apt2t27",
+ "finished": false,
+ "data": {
+ "qumbk3fkr6cky8850bvvq5z1": "Executive"
+ },
+ "meta": {
+ "userAgent": {
+ "os": "Mac OS",
+ "browser": "Chrome"
+ }
+ },
+ "personAttributes": {
+ "email": "test@web.com",
+ "userId": "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING"
+ },
+ "person": {
+ "id": "cljold01t0000qh8ewzigzmjk",
+ "attributes": {
+ "email": "test@web.com",
+ "userId": "THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING"
+ },
+ "createdAt": "2023-07-04T17:56:17.154Z",
+ "updatedAt": "2023-07-04T17:56:17.154Z"
+ },
+ "notes": [],
+ "tags": []
+ }
+ }
+ ```
+
+
+
+
diff --git a/apps/formbricks-com/app/docs/webhooks/page.mdx b/apps/formbricks-com/app/docs/webhooks/page.mdx
deleted file mode 100644
index e8f4612147..0000000000
--- a/apps/formbricks-com/app/docs/webhooks/page.mdx
+++ /dev/null
@@ -1,175 +0,0 @@
-export const metadata = {
- title: 'Webhooks',
- description:
- 'In this guide, we will look at how to register and consume webhooks to integrate your app with Protocol.',
-}
-
-# Webhooks
-
-In this guide, we will look at how to register and consume webhooks to integrate your app with Protocol. With webhooks, your app can know when something happens in Protocol, such as someone sending a message or adding a contact. {{ className: 'lead' }}
-
-## Registering webhooks
-
-To register a new webhook, you need to have a URL in your app that Protocol can call. You can configure a new webhook from the Protocol dashboard under [API settings](#). Give your webhook a name, pick the [events](#event-types) you want to listen for, and add your URL.
-
-Now, whenever something of interest happens in your app, a webhook is fired off by Protocol. In the next section, we'll look at how to consume webhooks.
-
-## Consuming webhooks
-
-When your app receives a webhook request from Protocol, check the `type` attribute to see what event caused it. The first part of the event type will tell you the payload type, e.g., a conversation, message, etc.
-
-```json {{ title: 'Example webhook payload' }}
-{
- "id": "a056V7R7NmNRjl70",
- "type": "conversation.updated",
- "payload": {
- "id": "WAz8eIbvDR60rouK"
- // ...
- }
-}
-```
-
-In the example above, a conversation was `updated`, and the payload type is a `conversation`.
-
-
-
-
-
----
-
-## Event types
-
-
-
-
-
-
- A new contact was created.
-
-
- An existing contact was updated.
-
-
- A contact was successfully deleted.
-
-
- A new conversation was created.
-
-
- An existing conversation was updated.
-
-
- A conversation was successfully deleted.
-
-
- A new message was created.
-
-
- An existing message was updated.
-
-
- A message was successfully deleted.
-
-
- A new group was created.
-
-
- An existing group was updated.
-
-
- A group was successfully deleted.
-
-
- A new attachment was created.
-
-
- An existing attachment was updated.
-
-
- An attachment was successfully deleted.
-
-
-
-
-
-
- ```json {{ 'title': 'Example payload' }}
- {
- "id": "a056V7R7NmNRjl70",
- "type": "message.updated",
- "payload": {
- "id": "SIuAFUNKdSYHZF2w",
- "conversation_id": "xgQQXg3hrtjh7AvZ",
- "contact": {
- "id": "WAz8eIbvDR60rouK",
- "username": "KevinMcCallister",
- "phone_number": "1-800-759-3000",
- "avatar_url": "https://assets.protocol.chat/avatars/kevin.jpg",
- "last_active_at": 705103200,
- "created_at": 692233200
- },
- "message": "I’m traveling with my dad. He’s at a meeting. I hate meetings.",
- "reactions": [],
- "attachments": [],
- "read_at": 705103200,
- "created_at": 692233200,
- "updated_at": 692233200
- }
- }
- ```
-
-
-
-
----
-
-## Security
-
-To know for sure that a webhook was, in fact, sent by Protocol instead of a malicious actor, you can verify the request signature. Each webhook request contains a header named `x-protocol-signature`, and you can verify this signature by using your secret webhook key. The signature is an HMAC hash of the request payload hashed using your secret key. Here is an example of how to verify the signature in your app:
-
-
-
-```js
-const signature = req.headers['x-protocol-signature']
-const hash = crypto.createHmac('sha256', secret).update(payload).digest('hex')
-
-if (hash === signature) {
- // Request is verified
-} else {
- // Request could not be verified
-}
-```
-
-```python
-from flask import request
-import hashlib
-import hmac
-
-signature = request.headers.get("x-protocol-signature")
-hash = hmac.new(bytes(secret, "ascii"), bytes(payload, "ascii"), hashlib.sha256)
-
-if hash.hexdigest() == signature:
- # Request is verified
-else:
- # Request could not be verified
-```
-
-```php
-$signature = $request['headers']['x-protocol-signature'];
-$hash = hash_hmac('sha256', $payload, $secret);
-
-if (hash_equals($hash, $signature)) {
- // Request is verified
-} else {
- // Request could not be verified
-}
-```
-
-
-
-If your generated signature matches the `x-protocol-signature` header, you can be sure that the request was truly coming from Protocol. It's essential to keep your secret webhook key safe — otherwise, you can no longer be sure that a given webhook was sent by Protocol. Don't commit your secret webhook key to GitHub!
diff --git a/apps/formbricks-com/app/not-found.tsx b/apps/formbricks-com/app/not-found.tsx
index 50de0327ac..f4e07efdf7 100644
--- a/apps/formbricks-com/app/not-found.tsx
+++ b/apps/formbricks-com/app/not-found.tsx
@@ -1,17 +1,13 @@
-import { Button } from '@/app/docs/_components/Button'
-import { HeroPattern } from '@/app/docs/_components/HeroPattern'
+import { Button } from "@/components/docs/Button";
+import { HeroPattern } from "@/components/docs/HeroPattern";
export default function NotFound() {
return (
<>
-
- 404
-
-
- Page not found
-
+
404
+
Page not found
Sorry, we couldn’t find the page you’re looking for.
@@ -20,5 +16,5 @@ export default function NotFound() {
>
- )
+ );
}
diff --git a/apps/formbricks-com/components/docs/BestPractices.tsx b/apps/formbricks-com/components/docs/BestPractices.tsx
new file mode 100644
index 0000000000..6010bbc5c0
--- /dev/null
+++ b/apps/formbricks-com/components/docs/BestPractices.tsx
@@ -0,0 +1,167 @@
+"use client";
+
+import Link from "next/link";
+import { type MotionValue, motion, useMotionTemplate, useMotionValue } from "framer-motion";
+
+import { GridPattern } from "./GridPattern";
+import { Heading } from "./Heading";
+import { ChatBubbleIcon } from "@/components/docs/icons/ChatBubbleIcon";
+import { EnvelopeIcon } from "@/components/docs/icons/EnvelopeIcon";
+import { UserIcon } from "@/components/docs/icons/UserIcon";
+import { UsersIcon } from "@/components/docs/icons/UsersIcon";
+
+interface BestPractice {
+ href: string;
+ name: string;
+ description: string;
+ icon: React.ComponentType<{ className?: string }>;
+ pattern: Omit, "width" | "height" | "x">;
+}
+
+const bestPractices: Array = [
+ {
+ href: "/docs/best-practices/cancel-subscription",
+ name: "Learn from Churn",
+ description: "Churn is hard, but can teach you a lot. These insights are pure gold to reduce churn.",
+ icon: UserIcon,
+ pattern: {
+ y: 16,
+ squares: [
+ [0, 1],
+ [1, 3],
+ ],
+ },
+ },
+ {
+ href: "/docs/best-practices/pmf-survey",
+ name: "Product Market Fit",
+ description:
+ "Measuring and understanding your PMF helps you understand what users like, what they’re missing and what to build next.",
+ icon: ChatBubbleIcon,
+ pattern: {
+ y: -6,
+ squares: [
+ [-1, 2],
+ [1, 3],
+ ],
+ },
+ },
+ {
+ href: "/docs/best-practices/improve-trial-cr",
+ name: "Improve Trial Conversion",
+ description: "When a user doesn't convert, you want to know why.",
+ icon: EnvelopeIcon,
+ pattern: {
+ y: 32,
+ squares: [
+ [0, 2],
+ [1, 4],
+ ],
+ },
+ },
+ {
+ href: "/docs/best-practices/feedback-box",
+ name: "Feedback Box",
+ description: "The Feedback Box gives your users a direct channel to share their feedback and feel heard.",
+ icon: UsersIcon,
+ pattern: {
+ y: 22,
+ squares: [[0, 1]],
+ },
+ },
+];
+
+function BestPracticeIcon({ icon: Icon }: { icon: BestPractice["icon"] }) {
+ return (
+