Building a User Feedback Widget with Vue.js and Directus

building-a-user-feedback-widget-with-vue.js-and-directus

One of our DevRel initiatives at Directus is constantly improving our documentation. As a small team with finite time and resources, we rely a lot on user feedback to help guide our writing efforts. But we were missing the most important bit there – your feedback.

What We’re Building

At the time of this post, the Directus Docs runs on VitePress (which in turn is based on Vue.js and Vite). Vitepress is a nice bit of kit for quickly generating a static documentation site, but sadly there’s no built-in feature for gathering user feedback.

So I decided to build my own so our team could make better decisions on where to spend our precious time and attention.

While this project was built in the context of Vitepress, this post will show you how to do it with Vue generally. Here’s what our finished product will look like.

Screenshot of Directus documentation article with a highlighted feedback widget at the bottom of the screen.

Prerequisites

Before we hop 🐰 in , here’s what you’ll need to follow along:

Knowledge

  • Beginner knowledge of Javascript, Typescript, and Vue.js (Composition API)

Tooling

Preparing Directus Collection

First off, we’re going to need a place to store all this valuable feedback we’ll be gathering.

Create a docs_feedback collection with the following data model:

docs_feedback

- id (Type: uuid)
- date_created (Type: Timestamp, Interface: Date/Time)
- url (Type: String, Interface: Input)
- rating (Type: Integer, Interface: Slider)
- title (Type: String, Interface: Input)
- comments (Type: Text, Interface: Textarea)

Creating Vue Component for Article Feedback

Just as if it were the lone dev on a cross-functional team – we’re going to place a lot of different responsibilities on our hard-working little Vue component.

  • Rating System: We’ll use a 1 to 4 scale, with each value associated with a different message. These messages will help engage users and guide them through the feedback process.
  • Open Ended Feedback: We provide a text area for users to write their thoughts. This is where the gold is. We want users to share their ideas, suggestions, and insights – positive or constructive 😭.
  • Posting Data to Directus: The component handles the submission of the feedback to Directus. It constructs the feedback object and makes a POST request to the feedback API endpoint.

Scaffolding the Feedback Component

Create a new file in our components directory named ArticleFeedback.vue . Then copy and paste the following code.

<script setup lang="ts">
script>

<template>
     class="wrapper">
         class="step">
            
            
class="desc">How can we improve?

class="heading">How helpful was this article?

class="step">
class="step">
template> <style scoped> style>

We’ve got three different states (or steps as I’m calling them) we’ll need to build.

  1. An initial state that shows the feedback prompt and rating buttons.
  2. Once a rating has been selected, a state which asks for comments and feedback.
  3. A success state once form submission is complete.

Adding Props and Reactive Logic

Now let’s start adding our logic to control these three steps.






  1. Import the ref and reactive functions from Vue.
  2. We’ll pass the url and page title as props from the parent component that contains this widget.
  3. Create a reactive object feedback to manage our form submission data.
  4. Create a reactive success variable to hold the success state.
  5. Use v-if, v-else-if, and v-else to control what step of the feedback process is shown.

With the logic roughed in, let’s add our rating buttons.

Adding the Rating Options




The rating options will be an array of objects that have a visible label, a corresponding value of 1-4, and a dynamicmessage that we’ll display to encourage the user to leave comments after selecting a rating.

We’ll also create a small helper function to return the rating object based when passing a number value. This will come in handy in the second step because we’re going to display the rating the user chose.

Add a new div to Step 1 below the feedback prompt that will contain our rating options. Inside that, we’ll use v-for to loop through the ratingOptions array and render the individual buttons.

Asking for Comments