Creating a chatbot using VueJS

By Charlie,

October 2020

Web Dev
Over the past few years the use of chatbots has become more popular. They create an easy way to perform tasks or answer questions without the need for human interaction. We received a request to add a chatbot to one of our latest builds, and I felt VueJS was perfect for this.

Wolfestone came to us wanting to have an easy way to triage their enquiries and understand which of their services would be best based on their customer's needs.

They gave us a series of questions they ask clients about a project. By answering these questions, they know what service they would recommend.

The Design

No one wants to feel like they’re talking to a robot. So the design needed to reflect the feeling that you were chatting to a real person.

We created a chatbot design based on mobile messaging. We used an avatar and three animated dots, to make it seem as if someone was in the process of writing a response. This brought a personal touch to the component.

Wolfestone Chatbot

Building the chatbot

Within the JS Framework market, React and Angular have dominated for years. Then Vue joined the race. Vue is my preferred JS Framework. It’s versatile, lightweight and can be used in a multitude of scenarios.

The best way for us to tackle the chatbot was to make each question an object, containing the question, answers and a unique identifier (ID)

const quiz = {    
    questions: [
            id: 'a',
            text: "Is the translation for basic understanding?",
            responses: [{
                    text: 'Yes',
                    icon: 'icon-thumbs-up',
                    answer: 'e'
                    text: 'No',
                    icon: 'icon-thumbs-down',
                    answer: 'b'

Each of the final answers needed to have two additional attributes:

  • Service
  • Query String

The query string is attached to a CTA link added with the answer, which leads the user to a contact form. This query string is used by a hidden field within the form, which lets Wolfestone know which service has been recommended once the form is submitted.

    id: 'final-a',
    services: '<strong>AI</strong> or <strong>Rapid</strong>',
    query: 'AI or Rapid',

The fun part!

Once the array had been built, we could begin integrating Vue to make the chatbot interactive.

The site is built using Craft CMS, which uses Twig for templating. We needed to set up a Vue Instance within Javascript, and the markup for the chatbot using Twig.

Using an ID for the elements, we were able to connect the two, and start using Vue’s markup to make sure the data was being passed through correctly. However as Vue uses the same default delimiter as Twig, (curly brackets) it was also important to change this, to keep the readability as clear as possible. This is very simple to do . We just added the following to the Vue instance:

delimiters: ['${', '}']

Getting started with Vue

Within our Vue instance we used four properties:

  • Data
  • Updated
  • Mounted
  • Methods

This property contains the data we want to process. This contains the array of questions, and a question index.


This property runs each time the instance data gets updated. We used this to initiate a new event, which is used to trigger the texting animations.


Similar to the Updated property, however this is triggered once the Vue instance has collated all of it’s data on load.


This is where we create the functions which make the magic happen. This includes finding the related questions/answers, resetting the chatbot once you reach the end, and adding/removing classes for the animation.

We integrated AOS into Vue to handle the animations. This helped keep the code clean, but also meant we could use data attributes instead of classes. Using Data attributes helps to reduce the risk of conflict from third party code, while also keeping our code readable.

const app = new Vue({
    created () {
            once: true,
    el: '#quiz-questions',
    delimiters: ['${', '}'],
    data: {
        quiz: quiz,
        questionIndex: 0,
    updated: function() {
        this.$nextTick(function () {
    mounted: function() {
        this.$nextTick(function () {
    methods: {
        // Find the Next Question / Final Message based on the ID.
        findRelated(value) {                
            const questions = this.quiz.questions;
            for(var i=0; i < questions.length; i++){
                if( questions[i].id == value){
                    this.questionIndex = [i][0];
        // Reset the Quiz to the beginning
        resetQuiz() {
            this.questionIndex = 0;
        // Trigger event when question has loaded
        triggerEvent() {
            setTimeout(function() {
            }, 1600);

Building the Twig Template

Performance was important during the build process. We wanted to make sure that only the relevant question was being loaded, which is done using v-ifand v-bind.

<div class="quiz__container" 
    v-if="questionIndex < quiz.questions.length" 

We then loop through the question’s object and display the correct text and responses.

${ quiz.questions[questionIndex].message }

On each of the responses we add a method function to be used when clicked, by adding:


Vue uses this to display the question with the correct ID.


Wolfestone wanted an interactive way for their clients to understand which of their services would be best for their project. With VueJS we were able to deliver a chatbot which is friendlier and more engaging than a simple form, while also keeping the code minimal and performant. You can see the finished feature on Wolfestone’s new Craft Website.

If you need to evolve how your customers engage with you, or create a unique bespoke experience for your site, we can help. Speak to our team about your project.