Add Link Prefilling, UserId Prefilling and Nextjs App Dir Setup to Docs (#480)
* fix EventClassesList table * doc update * update docs * update nextjs docs * update prefilling docs with url encoding --------- Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
@@ -21,13 +21,16 @@ export default function AppPage({}) {
|
||||
</p>
|
||||
<Image src={fbsetup} alt="fb setup" className="mt-4 rounded" priority />
|
||||
</div>
|
||||
{/* <div className="mt-4 rounded-lg border border-slate-300 bg-slate-100 p-6">
|
||||
<h3 className="text-lg font-semibold">Console</h3>
|
||||
<p className="text-slate-700">You can also open your browser console to logs:</p>
|
||||
<div className="max-h-[40vh] overflow-y-auto py-4">
|
||||
<div className="mt-4 rounded-lg border border-slate-300 bg-slate-100 p-6">
|
||||
<h3 className="text-lg font-semibold">Widget Logs</h3>
|
||||
<p className="text-slate-700">
|
||||
Look at the logs to understand how the widget works. <strong>Open your browser console</strong>{" "}
|
||||
to see the logs.
|
||||
</p>
|
||||
{/* <div className="max-h-[40vh] overflow-y-auto py-4">
|
||||
<LogsContainer />
|
||||
</div>
|
||||
</div> */}
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:grid md:grid-cols-3">
|
||||
|
||||
@@ -23,7 +23,7 @@ export const DocsFeedback: React.FC = () => {
|
||||
<div className="mt-6 inline-flex cursor-default items-center rounded-md border border-slate-200 bg-white p-4 text-slate-800 dark:border-slate-700 dark:bg-slate-800 dark:text-slate-300">
|
||||
{!sharedFeedback ? (
|
||||
<div className="text-center md:text-left">
|
||||
Was this page helpful?
|
||||
Is everything on this page clear?
|
||||
<Popover open={isOpen} onOpenChange={setIsOpen}>
|
||||
<div className="mt-2 inline-flex space-x-3 md:ml-4 md:mt-0">
|
||||
{["Yes 👍", " No 👎"].map((option) => (
|
||||
|
||||
@@ -11,7 +11,8 @@ const navigation = [
|
||||
title: "Getting Started",
|
||||
links: [
|
||||
{ title: "Quickstart", href: "/docs/getting-started/quickstart" },
|
||||
{ title: "Setup with Next.js", href: "/docs/getting-started/nextjs" },
|
||||
{ title: "Next.js App Dir", href: "/docs/getting-started/nextjs-app" },
|
||||
{ title: "Next.js Pages Dir", href: "/docs/getting-started/nextjs-pages" },
|
||||
{ title: "Setup with Vue.js", href: "/docs/getting-started/vuejs" },
|
||||
],
|
||||
},
|
||||
@@ -43,6 +44,13 @@ const navigation = [
|
||||
{ title: "Docs Feedback", href: "/docs/best-practices/docs-feedback" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Link Surveys",
|
||||
links: [
|
||||
{ title: "Data Prefilling", href: "/docs/link-surveys/data-prefilling" },
|
||||
{ title: "User Identification", href: "/docs/link-surveys/user-identification" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "API",
|
||||
links: [
|
||||
@@ -77,6 +85,8 @@ const navigation = [
|
||||
links: [
|
||||
{ title: "Introduction", href: "/docs/contributing/introduction" },
|
||||
{ title: "Setup Dev Environment", href: "/docs/contributing/setup" },
|
||||
{ title: "Demo App", href: "/docs/contributing/demo" },
|
||||
{ title: "Troubleshooting", href: "/docs/contributing/troubleshooting" },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -46,6 +46,11 @@ const nextConfig = {
|
||||
destination: "/docs/introduction/what-is-formbricks",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/docs/getting-started/nextjs",
|
||||
destination: "/docs/getting-started/nextjs-app",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/docs/formbricks-hq/self-hosting",
|
||||
destination: "/docs",
|
||||
|
||||
@@ -27,7 +27,7 @@ The API requests are authorized with a personal API key. This API key gives you
|
||||
|
||||
### Delete a personal API key
|
||||
|
||||
1. Go to settings on [app.formbricks.com](https://app.formbricks.com/app/me/settings).
|
||||
1. Go to settings on [app.formbricks.com](https://app.formbricks.com/me/settings).
|
||||
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.
|
||||
|
||||
@@ -43,33 +43,15 @@ To get this running, you'll need a bit of time. Here are the steps we're going t
|
||||
|
||||
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”:
|
||||
|
||||
<Image
|
||||
src={SwitchToDev}
|
||||
alt="switch to dev environment"
|
||||
quality="100"
|
||||
className="rounded-lg"
|
||||
className="rounded"
|
||||
/>
|
||||
<Image src={SwitchToDev} alt="switch to dev environment" quality="100" className="rounded-lg" />
|
||||
|
||||
3. Then, create a survey using the template “Docs Feedback”:
|
||||
|
||||
<Image
|
||||
src={DocsTemplate}
|
||||
alt="select docs template"
|
||||
quality="100"
|
||||
className="rounded-lg"
|
||||
className="rounded"
|
||||
/>
|
||||
<Image src={DocsTemplate} alt="select docs template" quality="100" className="rounded-lg" />
|
||||
|
||||
4. Change the Internal Question ID of the first question to **“isHelpful”** to make your life easier 😉
|
||||
|
||||
<Image
|
||||
src={ChangeId}
|
||||
alt="switch to dev environment"
|
||||
quality="100"
|
||||
className="rounded-lg"
|
||||
className="rounded"
|
||||
/>
|
||||
<Image src={ChangeId} alt="switch to dev environment" quality="100" className="rounded-lg" />
|
||||
|
||||
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”**.
|
||||
|
||||
@@ -80,13 +62,7 @@ To get this running, you'll need a bit of time. Here are the steps we're going t
|
||||
|
||||
6. Click on “Continue to Settings or select the audience tab manually. Scroll down to “When to ask” and create a new Action:
|
||||
|
||||
<Image
|
||||
src={WhenToAsk}
|
||||
alt="set up when to ask card"
|
||||
quality="100"
|
||||
className="rounded-lg"
|
||||
className="rounded"
|
||||
/>
|
||||
<Image src={WhenToAsk} alt="set up when to ask card" quality="100" className="rounded-lg" />
|
||||
|
||||
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:
|
||||
|
||||
@@ -94,7 +70,7 @@ To get this running, you'll need a bit of time. Here are the steps we're going t
|
||||
|
||||
8. Select the Non-Event in the dropdown. Now you see that the “Publish survey” button is active. Publish your survey 🤝
|
||||
|
||||
<Image src={SelectNonevent} alt="select nonevent" quality="100" className="rounded-lg" className="rounded" />
|
||||
<Image src={SelectNonevent} alt="select nonevent" quality="100" className="rounded-lg" />
|
||||
|
||||
**You’re all setup in Formbricks Cloud for now 👍**
|
||||
|
||||
@@ -280,7 +256,7 @@ return (
|
||||
|
||||
## 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](https://formbricks.com/docs/api/create-response)” and “[Update Response](https://formbricks.com/docs/api/update-response)” pages in our docs.
|
||||
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:
|
||||
|
||||
@@ -373,7 +349,7 @@ Before you roll it out in production, you want to test it. To do so, you need tw
|
||||
|
||||
When you are on the survey detail page, you’ll find both of them in the URL:
|
||||
|
||||
<Image src={CopyIds} alt="copy IDs" quality="100" className="rounded-lg" className="rounded" />
|
||||
<Image src={CopyIds} alt="copy IDs" quality="100" className="rounded-lg" />
|
||||
|
||||
Now, you have to replace the IDs and the API host accordingly in your `handleFeedbackSubmit`:
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 59 KiB |
@@ -0,0 +1,67 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
import { Fence } from "@/components/shared/Fence";
|
||||
import { Callout } from "@/components/shared/Callout";
|
||||
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.",
|
||||
};
|
||||
|
||||
To play around with the user actions, 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.
|
||||
|
||||
<Image src={DemoApp} alt="Demo App Preview" quality="100" className="rounded-lg" />
|
||||
|
||||
## Functionality
|
||||
|
||||
### Code Action
|
||||
|
||||
This button sends a <a href="/docs/actions/code">Code Action</a> 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 <a href="/docs/actions/no-code">No Code Action</a> 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
|
||||
<button>No-Code Action</button>
|
||||
```
|
||||
|
||||
### Set Plan to "Free"
|
||||
|
||||
This button sets the <a href="/docs/attributes/custom-attributes">attribute</a> '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 <a href="/docs/attributes/custom-attributes">attribute</a> 'Plan' to 'Paid'. If the attribute does not exist, it creates it.
|
||||
|
||||
```tsx
|
||||
formbricks.setAttribute("Plan", "Paid");
|
||||
```
|
||||
|
||||
### Set Email
|
||||
|
||||
This button sets the <a href="/docs/attributes/identify-users">user email</a> 'test@web.com'
|
||||
|
||||
```tsx
|
||||
formbricks.setEmail("test@web.com");
|
||||
```
|
||||
|
||||
### Set UserId
|
||||
|
||||
This button sets an external <a href="/docs/attributes/identify-users">user ID</a> to 'THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING'
|
||||
|
||||
```tsx
|
||||
formbricks.setUserId("THIS-IS-A-VERY-LONG-USER-ID-FOR-TESTING");
|
||||
```
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
|
After Width: | Height: | Size: 27 KiB |
@@ -0,0 +1,65 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
import { Fence } from "@/components/shared/Fence";
|
||||
import { Callout } from "@/components/shared/Callout";
|
||||
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.",
|
||||
};
|
||||
|
||||
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:
|
||||
|
||||
<Image src={ClearAppData} alt="Demo App Preview" quality="100" className="rounded-lg" />
|
||||
|
||||
## "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
|
||||
|
||||
<Image src={UncaughtPromise} alt="Uncaught promise" quality="100" className="rounded-lg" />
|
||||
|
||||
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.
|
||||
|
||||
<Image src={Logout} alt="Logout Person" quality="100" className="rounded-lg" />
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,97 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
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.",
|
||||
};
|
||||
|
||||
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:
|
||||
|
||||
<Image src={SetupChecklist} alt="Step 2 - Setup Checklist" quality="100" className="rounded-lg" />
|
||||
|
||||
## 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.js` file (or formbricks.ts if you are using Typescript) and set up the FormbricksProvider with the 'use client' directive:
|
||||
|
||||
```tsx
|
||||
// app/formbricks.js
|
||||
"use client";
|
||||
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
|
||||
logLevel: "debug", // remove when in production
|
||||
});
|
||||
}
|
||||
|
||||
export default function Providers({ Component, pageProps }: AppProps) {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
useEffect(() => {
|
||||
formbricks?.registerRouteChange();
|
||||
}, [pathname, searchParams]);
|
||||
|
||||
return null;
|
||||
}
|
||||
```
|
||||
|
||||
Once we do this, we can then import the `provider.js` file in our `app/layout.js` file, and wrap our app in the Formbricks provider.
|
||||
|
||||
```tsx
|
||||
// app/layout.js
|
||||
import Providers from "./formbricks";
|
||||
|
||||
export const metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<Providers />
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
<Image src={WidgetNotConnected} alt="Widget isnt connected" quality="100" className="rounded-lg" />
|
||||
|
||||
To this:
|
||||
|
||||
<Image src={WidgetConnected} alt="Widget is connected" quality="100" className="rounded-lg" />
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,88 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
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.",
|
||||
};
|
||||
|
||||
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:
|
||||
|
||||
<Image src={SetupChecklist} alt="Step 2 - Setup Checklist" quality="100" className="rounded-lg" />
|
||||
|
||||
## 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
|
||||
logLevel: "debug", // 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 <Component {...pageProps} />;
|
||||
}
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
<Image src={WidgetNotConnected} alt="Widget isnt connected" quality="100" className="rounded-lg" />
|
||||
|
||||
To this:
|
||||
|
||||
<Image src={WidgetConnected} alt="Widget is connected" quality="100" className="rounded-lg" />
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
@@ -1,82 +0,0 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
|
||||
export const meta = {
|
||||
title: "Setting up Formbricks SDK with Next.js",
|
||||
description: "Integrate Formbricks SDK into your Next.js app for seamless in-product micro-surveys. Follow our step-by-step guide to enhance user feedback and product experience.",
|
||||
};
|
||||
|
||||
This guide will walk you through the process of integrating the Formbricks SDK into a Next.js application. As the Formbricks SDK only works on the client side, it's essential to ensure proper integration to avoid any issues.
|
||||
|
||||
## Introduction
|
||||
|
||||
Formbricks SDK allows you to seamlessly integrate in-product micro-surveys into your Next.js application. By following the steps outlined in this guide, you'll be able to gather valuable insights from your users and improve your product experience.
|
||||
|
||||
## 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 Formbricks SDK with Next.js
|
||||
|
||||
Update your App component in the \_app.ts file like so:
|
||||
|
||||
```tsx
|
||||
import "@/styles/globals.css";
|
||||
import type { AppProps } 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
|
||||
logLevel: "debug", // remove when in production
|
||||
});
|
||||
}
|
||||
|
||||
export default function App({ Component, pageProps }: AppProps) {
|
||||
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 <Component {...pageProps} />;
|
||||
}
|
||||
```
|
||||
|
||||
**What are we doing here?**
|
||||
First we need to initialize the Formbricks SDK, making sure it only runs on the client side.
|
||||
|
||||
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.
|
||||
|
||||
That's it! 🎉
|
||||
|
||||
You should now see that the Widget Status in the setup checklist updated accordingly:
|
||||
|
||||
If it doesnt work, please [join our Discord](https://formbricks.com/discord) and let us know!
|
||||
|
||||
You have now successfully integrated the Formbricks SDK into your Next.js application. You can start creating and customizing in-product micro-surveys to gather valuable feedback from your users and improve your product experience.
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
@@ -0,0 +1,115 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
import { Fence } from "@/components/shared/Fence";
|
||||
import { Callout } from "@/components/shared/Callout";
|
||||
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.",
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
```tsx
|
||||
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/).
|
||||
|
||||
<Callout title="Prefill only the first question" type="note">
|
||||
Currently, you can only prefill the first question of a link survey.
|
||||
</Callout>
|
||||
|
||||
## 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:
|
||||
|
||||
<Image
|
||||
src={QuestionId}
|
||||
alt="The question Id is located at the bottom of each question card in the survey editor."
|
||||
quality="100"
|
||||
className="rounded-lg"
|
||||
/>
|
||||
|
||||
## Examples
|
||||
|
||||
Here are a few examples to get you started:
|
||||
|
||||
### Rating Question
|
||||
|
||||
```tsx
|
||||
https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?rating_question_id=5
|
||||
|
||||
// -> translates to 5 stars / points / emojis
|
||||
```
|
||||
|
||||
### NPS Question
|
||||
|
||||
```tsx
|
||||
https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?nps_question_id=10
|
||||
|
||||
// -> translates to an NPS rating of 10
|
||||
```
|
||||
|
||||
### Single Select Question (Radio)
|
||||
|
||||
```tsx
|
||||
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)
|
||||
|
||||
```tsx
|
||||
https://app.formbricks.com/s/clin3yxja52k8l80hpwmx4bjy?single_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
|
||||
|
||||
```tsx
|
||||
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
|
||||
|
||||
```tsx
|
||||
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! 🎉
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,57 @@
|
||||
import { Layout } from "@/components/docs/Layout";
|
||||
import { Fence } from "@/components/shared/Fence";
|
||||
import { Callout } from "@/components/shared/Callout";
|
||||
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.",
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
```tsx
|
||||
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.
|
||||
|
||||
<Image
|
||||
src={PeopleView}
|
||||
alt="If users are identified by email, it will show. If not, the internal Id will be set."
|
||||
quality="100"
|
||||
className="rounded-lg"
|
||||
/>
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>;
|
||||
|
After Width: | Height: | Size: 16 KiB |
@@ -45,13 +45,11 @@ export default function EventClassesList({ environmentId }) {
|
||||
</Button>
|
||||
</div>
|
||||
<div className="rounded-lg border border-slate-200">
|
||||
<div className="grid h-12 grid-cols-7 content-center rounded-lg bg-slate-100 text-left text-sm font-semibold text-slate-900">
|
||||
<div className="grid h-12 grid-cols-6 content-center rounded-lg bg-slate-100 text-left text-sm font-semibold text-slate-900">
|
||||
<span className="sr-only">Edit</span>
|
||||
<div className="col-span-4 pl-6 ">User Actions</div>
|
||||
<div className="text-center"># Reps</div>
|
||||
<div className="text-center">Created</div>
|
||||
<div className="text-center">
|
||||
<span className="sr-only">Edit</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-cols-7">
|
||||
{eventClasses.map((eventClass) => (
|
||||
@@ -61,7 +59,7 @@ export default function EventClassesList({ environmentId }) {
|
||||
}}
|
||||
className="w-full"
|
||||
key={eventClass.id}>
|
||||
<div className="m-2 grid h-16 grid-cols-7 content-center rounded-lg hover:bg-slate-100">
|
||||
<div className="m-2 grid h-16 grid-cols-6 content-center rounded-lg hover:bg-slate-100">
|
||||
<div className="col-span-4 flex items-center pl-6 text-sm">
|
||||
<div className="flex items-center">
|
||||
<div className="h-5 w-5 flex-shrink-0 text-slate-500">
|
||||
@@ -85,17 +83,7 @@ export default function EventClassesList({ environmentId }) {
|
||||
<div className="my-auto whitespace-nowrap text-center text-sm text-slate-500">
|
||||
{timeSinceConditionally(eventClass.createdAt)}
|
||||
</div>
|
||||
<div className="text-center">
|
||||
{/* {eventClass.type !== "automatic" && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
handleOpenEventDetailModalClick(e, eventClass);
|
||||
}}
|
||||
className="text-brand-dark hover:text-brand">
|
||||
Edit<span className="sr-only">, {eventClass.name}</span>
|
||||
</button>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="text-center"></div>
|
||||
</div>
|
||||
</button>
|
||||
))}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import AddNoCodeEventModal from "@/app/environments/[environmentId]/events/AddNoCodeEventModal";
|
||||
import LoadingSpinner from "@/components/shared/LoadingSpinner";
|
||||
import { useEventClasses } from "@/lib/eventClasses/eventClasses";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
@@ -7,7 +8,7 @@ import type { Survey } from "@formbricks/types/surveys";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Switch,
|
||||
Input,
|
||||
Label,
|
||||
Select,
|
||||
SelectContent,
|
||||
@@ -15,12 +16,11 @@ import {
|
||||
SelectSeparator,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
Input,
|
||||
Switch,
|
||||
} from "@formbricks/ui";
|
||||
import { CheckCircleIcon, PlusIcon, TrashIcon } from "@heroicons/react/24/solid";
|
||||
import * as Collapsible from "@radix-ui/react-collapsible";
|
||||
import { useEffect, useState } from "react";
|
||||
import AddNoCodeEventModal from "../../../events/AddNoCodeEventModal";
|
||||
|
||||
interface WhenToSendCardProps {
|
||||
localSurvey: Survey;
|
||||
|
||||