Create A Feedback Widget for Your React App
Tags: react, javascript, tailwindcss, nextjs
Published: 2021-10-19 00:49:42

You've created a new web app, launched successfully and acquired new users. Now what? You wonder are there bugs I'm missing? Are users enjoying the app? What features do they want added? 

This is a great time to add a feedback widget to your app. In Part 1, we'll show how to create a widget in react with NextJs, react-popper, and Tailwind

## Setting up our project


### Step 1: Create a new NextJs app


> **Note**: If you already have a react app you can skip to step 2


```npx create-next-app -e with-tailwindcss feedback-widget```

Open up the new app in your code editor, open up the `pages/index.js` file and delete out the contents. You should end up with: 

```javascript
import Head from "next/head";

export default function Home() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
      <Head>
        <title>React Feedback Widget Example</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      Hello!
    </div>
  );
}
 ```

### Step 2: Create feedback button


For this tutorial, we'll create a floating action button to trigger the feedback popup. This button will "float" at the bottom right of your page and will always be visible for the visitor/user to leave feedback. 

> **Note**: You can create any type of button that fits your project.


```javascript
import Head from "next/head";

export default function Home() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
      <Head>
        <title>React Feedback Widget Example</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <button
        className="absolute bottom-4 right-4 p-2 rounded-l-lg rounded-t-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
        type="button"
      >
        Feedback?
      </button>
    </div>
  );
}
```
We should now have something that looks like this:

![React Feedback Button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3l21a3ydrwcn1ofwrjh.png)

Next, we are ready to create the feedback widget. 

### Step 3: Install react-popper

```npm i react-popper @popperjs/core```

After installing, we'll need to import both `usePopper` and `useState` at the top of our component. 

```javascript
import { useState } from 'react';
import { usePopper } from 'react-popper';
```

Next, we'll set the popper reference and element. Full Code: 

```javascript
import { useState } from "react";
import { usePopper } from "react-popper";
import Head from "next/head";

export default function Home() {
  const [referenceElement, setReferenceElement] = useState(null);
  const [popperElement, setPopperElement] = useState(null);
   const { styles, attributes } = usePopper(referenceElement, popperElement, {
    modifiers: [{ name: "offset", options: { offset: [10, 10] } }],
  });
  return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
      <Head>
        <title>React Feedback Widget Example</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <button
        ref={setReferenceElement}
        className="absolute bottom-4 right-4 p-2 rounded-l-lg rounded-t-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
        type="button"
      >
        Feedback?
      </button>

      <div ref={setPopperElement}
style={styles.popper}
 {...attributes.popper}>
        Feedback Widget
    </div>
  );
}

```

We should now have both the button and popper element visible:

![React Feedback Widget Example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f4rdtoto2wvyn04u21t2.png)

Now let's add some styles to the popper.

### Step 4: Adding styles to the widget

Right now your widget doesn't have any styleing. We'll add some styling to make it look more like a widget. 

Add the classname below to the popper element: 

```   className="bg-white p-2 rounded-md shadow-lg" ```

Feel free to add different styling to make it your own!

### Step 5: Adding a feedback form to the widget

Now that we've created the widget, we'll need to create a form for the user to submit feedback. We want a text area where users can type their feedback, a label for the text area, and a submit button. 

```javascript
...
 <div
        className="bg-white p-2 rounded-md shadow-lg"
        ref={setPopperElement}
        style={styles.popper}
        {...attributes.popper}
      >
        <form>
          <label for="feedback">How can we improve?</label>
          <div className="flex flex-col space-y-2">
            <textarea
              id="feedback"
              className="p-2 h-24 w-64 border border-gray-400 rounded-md"
              type="textarea"
            ></textarea>
            <button
              className="p-2 ml-auto rounded-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
              type="submit"
            >
              Send Feedback
            </button>
          </div>
        </form>
      </div>
...
```
Now our widget should look like this: 

![React feedback widget](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vn01z01027jzyv3ibfq1.png)

### Step 6: Showing and hiding the widget

So we have our widget but now need to hide it on button click. We'll use `useState` for this: 

```javascript 
 const [showWidget, setShowWidget] = useState(false)
```

The feedback button will need a click handler to show and hide the widget: 

```javascript
... 
 <button
        onClick={() => setShowWidget(!showWidget)}
        ref={setReferenceElement}
        className="absolute bottom-4 right-4 p-2 rounded-l-lg rounded-t-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
        type="button"
      >
        Feedback?
      </button>
...
```

Now we'll need to conditionally show the widget when `showWidget = true`

```javascript
      {showWidget && (
        <div
          className="bg-white p-2 rounded-md shadow-lg"
          ref={setPopperElement}
          style={styles.popper}
          {...attributes.popper}
        >
          <form>
            <label for="feedback">How can we improve?</label>
            <div className="flex flex-col space-y-2">
              <textarea
                id="feedback"
                className="p-2 h-24 w-64 border border-gray-400 rounded-md"
                type="textarea"
              ></textarea>
              <button
                className="p-2 ml-auto rounded-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
                type="submit"
              >
                Send Feedback
              </button>
            </div>
          </form>
        </div>
      )}
```


Now we have a "functioning" feedback widget built with react, react-popper, and tailwind! 

<img width="100%" style="width:100%" src="https://media.giphy.com/media/dWIx9WozWDu7iXVkRW/giphy.gif">

Of course you'll need to create a backend to collect feedback and save it to your database. Don't have time for that? Use [SerVoice](https://www.servoice.io) and start collecting feedback within minutes. 

Full Code: 

```javascript 
import { useState } from "react";
import { usePopper } from "react-popper";
import Head from "next/head";

export default function Home() {
  const [showWidget, setShowWidget] = useState(false);
  const [referenceElement, setReferenceElement] = useState(null);
  const [popperElement, setPopperElement] = useState(null);
  const { styles, attributes } = usePopper(referenceElement, popperElement, {
    modifiers: [{ name: "offset", options: { offset: [10, 10] } }],
  });
  return (
    <div className="flex flex-col items-center justify-center min-h-screen py-2">
      <Head>
        <title>React Feedback Widget Example</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <button
        onClick={() => setShowWidget(!showWidget)}
        ref={setReferenceElement}
        className="absolute bottom-4 right-4 p-2 rounded-l-lg rounded-t-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
        type="button"
      >
        Feedback?
      </button>
      {showWidget && (
        <div
          className="bg-white p-2 rounded-md shadow-lg"
          ref={setPopperElement}
          style={styles.popper}
          {...attributes.popper}
        >
          <form>
            <label for="feedback">How can we improve?</label>
            <div className="flex flex-col space-y-2">
              <textarea
                id="feedback"
                className="p-2 h-24 w-64 border border-gray-400 rounded-md"
                type="textarea"
              ></textarea>
              <button
                className="p-2 ml-auto rounded-lg bg-blue-700 hover:bg-blue-600 shadow-md hover:shadow-lg text-white"
                type="submit"
              >
                Send Feedback
              </button>
            </div>
          </form>
        </div>
      )}
    </div>
  );
}
```

[Github Repo](https://github.com/servoice/react-feedback-widget-example)

### Want a part 2 where we create a backend? Leave a comment below.