Skip to content

Going Serverless with Vue.js and Firebase Cloud Functions

Going Serverless with Vue.js and Firebase Cloud Functions

Fire the base of Vue.js! - 3 Part Series

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

Welcome to a new episode of the Fire the base of Vue.js! series.

In this episode, I will integrate our Vue.js Notes Writer App with a serverless backend- specifically, the Firebase Cloud Functions.

If you haven’t read the other parts of this series, I highly recommend you do so before starting here.

Vue the Mirage from this angle! Storing your notes in the Cloud Firestore with Vue.js Firebase for user authentication in Vue.js

To follow up on the demo part of this article, you can use this GitHub source code repo as a starting point.

Firebase Cloud Functions, the concept

Cloud Functions are part of the Google Cloud Platform. You use them to write and deploy code that can respond to events coming from Google Cloud Services, including, but not limited to, the Firebase family of products.

With Cloud Functions, you piece together your application using different products. For instance, a user creates a new Document inside Firestore via the Web app. Consequently, a Cloud Function triggers, and responds to the event of Document Creation. The logic of a Cloud Function depends solely on the business scenario you are implementing.

Not only do they let you connect Google Cloud Services together, but they also allow you to create your own set of REST APIs to consume inside your Web or Mobile app.

The Cloud Functions project is a wrapper on top of the Google Cloud project. However, it was made easier for developers to configure and use.

The two major benefits Cloud Functions offer: Centralize your code in a safe way on Google Cloud Servers. Firebase Cloud Functions run on Google Servers. All of your apps, whether they be Web, Mobile or Desktop, can access and use them. Code security. It is better to save the access codes and keys for Firebase Services on the backend (on the Google Servers) rather than exposing them inside the client-side app code.

Cloud Functions are best used to: Trigger code in response to events coming from Firebase products. Perform writes to the Realtime Database and Firestore Upload to your Cloud Storage buckets. Respond to new accounts created in Firebase Authentication. Handle incoming HTTPs Request.

Firebase supports two flavors of Cloud Functions: HTTPs triggered Functions Background triggered Functions

Unlike Google Cloud Functions, Firebase Cloud Functions support only JavaScript/TypeScript with Node.js. The team is working on including more programming languages. Until then, let’s enjoy JavaScript!

HTTPs Triggered Cloud Functions

Let’s explore the anatomy of Cloud Functions for HTTPs triggers.

Start by ensuring Node.js version >= 8.13.0 is installed on your machine.

Next, install the Firebase CLI globally on your computer by running the following command:

npm install -g firebase-tools

Create a Firebase project by running the commands:

mkdir firebase-functions-http
cd firebase-functions-http

The next step is to log into Firebase services to connect the new project. Issue this:

firebase login

That command opens up a new tab in your default browser to ask for some permissions needed by the Firebase account.

Let’s initialize the Firebase project by running the following command:

firebase init

This command guides you through a command-line wizard to choose the Firebase features you want to add to the project.

For our case, let’s pick the following:

Which Firebase CLI features do you want to set up for this folder? Functions

What language would you like to use to write Cloud Functions? JavaScript

Do you want to use ESLint to catch probable bugs and enforce style? Yes

Do you want to install dependencies with npm now? Yes

That’s all!

Let the Firebase CLI do the project scaffolding, and get the project files ready.

Alt Text

The command scaffolds a Node.js project, and stores the Cloud Function related code inside the /functions folder.

The /functions.package.json lists all the dependencies needed by the Cloud Function. The most important dependencies are:

"dependencies": {
    "firebase-admin": "^8.9.2",
    "firebase-functions": "^3.3.0"
  },

Let’s make sure we have the latest bits of these packages by running the following command:

npm install firebase-admin@latest firebase-functions@latest

The /functions/index.js file contains the Cloud Function code.

const functions = require('firebase-functions');

exports.helloWorld = functions.https.onRequest((request, response) => {
    response.send("Hello from Firebase!");
});

The index.js file is a typical Node.js module file that exports a single Cloud Function named helloWorld. You can export more functions as needed.

The module starts by requiring the firebase-functions library. This library allows you to create Cloud Functions for HTTPs triggers. It exposes the onRequest() function. This function expects two parameters, the Request and Response objects. The callback function is required to return a Promise by issuing a call for response.send() function.

The popular Express.js module for Node.js is behind a Cloud Function for HTTPs trigger. When you deploy a Cloud Function on Firebase, it creates an Express.js app behind the scenes. This app will listen to any HTTPs request for /helloWorld, prepare a Request and Response object, and will call through your Cloud Function, passing it to the two objects.

You can include any code inside the onRequest() callback function like you do when writing Express.js apps.

I highly recommend reading this great article on dissecting the Express.js module, and learning how it’s made under the hood. Understanding how Express.js Works

Let’s run this Cloud Function locally by issuing the following command:

firebase serve --only functions

The command starts the Firebase Cloud Functions emulator to allow you to run the function locally, without the need to deploy it to Firebase servers.

✔  functions: Using node@10 from host.
✔  functions: Emulator started at http://localhost:5000
i  functions: Watching "/.../firebase-functions-http/functions" for Cloud Functions...
✔  functions[helloWorld]: http function initialized (http://localhost:5000/firebase-functions-http/us-central1/helloWorld).

Copy & Paste the Function URL into your browser, and you will see a plain text response of Hello from Firebase!.

To deploy the Cloud Function to Firebase platform, run the following command:

firebase deploy --only functions

Cloud Functions for HTTPs triggers can only be run under HTTPS and not HTTP.

Inside a Cloud Function for HTTPs trigger, you can call any other third party service. You can query the Firestore database, and return data from it, for instance.

You can always refer to the amazing Firebase Cloud Functions documentation to study the full range of capabilities supported by them.

Background Triggered Cloud Functions

The Background Triggered functions is the other type of functions offered and supported by Firebase.

Each and every product in the Firebase family exposes a set of events that are triggered upon a certain action.

For example, when a new Document is created inside Firestore, the OnCreate event is triggered.

Another example is when a new User is created in the Firebase Authentication module, the onCreate event is triggered.

exports.sendWelcomeEmail = functions.auth.user().onCreate((user) => {
  // ...
});

The functions object gives access to all supported types of Cloud Functions. This includes both the HTTPs, and Background triggered ones.

The example above gives you access to the user that was created. Then, you might decide to send the user an email, or push down a notification to the app. The sky's the limit!!

The Firebase Cloud Functions supports all Firebase products, and gives the developer the chance to handle many of the events triggered by them.

For a full list of all the supported background triggered functions, have a look at Trigger background functions

The Firebase Cloud Functions documentation is complete, and is extremely helpful to learning all the ins and outs. Therefore, without any further ado, let’s jump into our Notes App Writer, and add a new background triggered Cloud Function.

Demo

Clone the Notes App Writer at the add-auth branch. This is the branch we worked on in the previous article while authenticating users in the app.

Clone the app

Run the following command to clone the branch:

git clone --single-branch --branch add-auth git@github.com:bhaidar/notes-writer.git

Make sure to install all NPM packages by running this command:

npm install

Add support for Firebase Cloud Functions

If you haven’t logged into Firebase before, it’s time to do it by running this command:

firebase login

Once you log in, let’s initialize the Firebase services once again to include Functions this time.

firebase init

Follow the same steps mentioned in the HTTPs Triggered Cloud Functions section.

You will notice a new folder created under the root folder of the project named functions. This folder, as you know by now, holds all the source code for the Cloud Functions in your project.

It’s always important, whenever you add support for Cloud Functions in your project, to update the Firebase NPM packages by running the following command:

npm install firebase-admin@latest firebase-functions@latest

Use Environment Variables to store configuration settings

Let’s revisit the /firebaseConfig.js file. This file holds the Firebase connection settings as provided by Firebase Console.

I will make use of a hidden gem in Vue.js CLI v3, which allows you to use Environment Variables in your application to store such configuration settings. In fact, this is the recommended way of storing configuration settings in a Vue.js app rather than putting them in plain JSON or JavaScript files.

The CLI documentation referenced above gives you all the details about the Environment Variable files to use in your app. For now, create a new .env file at the root of the project, and paste the following keys:

VUE_APP_API_KEY=
VUE_APP_KEY_AUTH_DOMAIN=
VUE_APP_KEY_DATABASE_URL=
VUE_APP_PROJECT_ID=
VUE_APP_STORAGE_BUCKET=
VUE_APP_MESSAGING_SENDER_ID=
VUE_APP_ID=

Grab the actual keys from the Firebase Console and place them after they == sign on each and every line.

For instance,

VUE_APP_PROJECT_ID=notes-writer-f1e85

Going back to the firebaseConfig.js file, replace its content with the following:

import firebase from 'firebase/app'
import 'firebase/firestore'
import 'firebase/auth'

// firebase init
const config = {
  apiKey: process.env.VUE_APP_API_KEY,
  authDomain: process.env.VUE_APP_KEY_AUTH_DOMAIN,
  databaseURL: process.env.VUE_APP_KEY_DATABASE_URL,
  projectId: process.env.VUE_APP_PROJECT_ID,
  storageBucket: process.env.VUE_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.VUE_APP_MESSAGING_SENDER_ID,
  appId: process.env.VUE_APP_ID
}

firebase.initializeApp(config)

// firebase db
const db = firebase.firestore()

// firebase auth
const auth = firebase.auth()

// firebase collections
const notesCollection = db.collection('notes')

export {
  auth,
  db,
  firebase,
  notesCollection
}

Implement the Cloud Function

Let’s visit the functions/index.js file, and start implementing our function logic.

The purpose of this function is to listen to any new Note Document created inside Firestore, grab its details, and send them in an email.

Replace the contents of the index.js file with the following:

const functions = require('firebase-functions')
const admin = require('firebase-admin')

admin.initializeApp()

exports.onNewNoteCreated =
  functions.firestore.document('notes/{notesId}').onCreate((snap, context) => {
    const { body } = snap.data()
    const { params: { notesId } } = context

    console.log(context)
    console.log(body)
    console.log(notesId)

    return Promise.resolve(true)
  })

The JavaScript module imports the Firebase Functions Admin SDK libraries.

The Firebase Admin SDK lets you interact with Firebase from privileged environments to perform several actions.

The module exposes a single Cloud Function named onNewNoteCreated. This function subscribes to the OnCreate() event handler to run once a new Firestore Document is created.

The onCreate() event handler accepts as callback function having two parameters: DocumentSnapshot. EventContext.

The former parameter lets you access the content of the Document created, while the latter lets you access the context in which the event has occurred.

The next line extracts the body property of the Notes Document. Then, the code extracts the notesId from the EventContext parameter.

The variables are then logged to the Cloud Functions Logs database. From my experience, the Cloud Functions Logs is the best tool to debug and test your functions!

Finally, the function returns a resolved Promise. I will further discuss the concept of returning Promises from Cloud Functions in the next section of this article.

Let’s run the Cloud Function locally first by using the Firebase Functions Shell.

Run the following command:

firebase functions:shell
``

You use the Functions Shell to test your functions interactively. You can read more about it by following this link: [Test functions interactively](https://firebase.google.com/docs/functions/local-shell)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yb0oljjnidl4ix4es15z.png)

Behind the scenes, the Shell loads the Functions emulator, and lists them all for reference.

To execute a single function, simply run the following on the **firebase** command line:

```bash
onNewNoteCreated({ body: "Hello Firebase Functions!" }, { params: { notesId: "note-#001" }})

Hit Enter!

The output is as follows:


'Successfully invoked function.'

firebase > >  

{ eventId: 'c6f8eec2-e7e0-463e-9966-c8c8b0a25505',
>    timestamp: '2020-02-15T08:12:02.088Z',
>    eventType: 'google.firestore.document.create',
>    resource:
>     { service: 'firestore.googleapis.com',
>       name:
>        'projects/notes-writer-f1s85/databases/(default)/documents/notes/note-#001' },
>    params: { notesId: 'note-#001' } }

>  Hello Firebase Functions!

>  note-#001

The first block of text represents the ExecutionContext object. It gives you details about the current event, and its context. For instance, the event type is a google.firestore.document.create. The full path of the new document shows inside the resource property. Finally, your Cloud Function has access to the params property that includes the ID of the new Notes Document.

The second block of text prints the body of the new Note Document.

Finally, the third block of text prints the notesId grabbed from the params property on the ExecutionContext object.

Send an email inside the Cloud Function

Let’s make our Cloud Function more useful! You have many options to do so with the Firebase family of products.

For instance, we could send the new Note as a Push Notification using the Firebase Cloud Messaging product. However, I would rather not introduce more than one Firebase product in one article.

Let’s, instead, send the contents of the new Note Document using an email. For that, we need to install an additional NPM package to allow us to send the email.

Make sure you are inside the /functions folder, run the following command:

npm install nodemailer

We are going to use the nodemailer Node.js module to send out the emails.

Replace the contents of the /functions/index.js with the following code:

const functions = require('firebase-functions')
const admin = require('firebase-admin')
const nodemailer = require('nodemailer')

admin.initializeApp()

var transporter = nodemailer.createTransport({
  host: 'smtp.gmail.com',
  port: 465,
  secure: true,
  auth: {
    user: '',
    pass: ''
  }
})

exports.onNewNoteCreated =
  functions.firestore.document('notes/{notesId}').onCreate((snap, context) => {
    const { body } = snap.data()
    const { params: { notesId } } = context

    console.log(body)
    console.log(notesId)

    const mailOptions = {
      from: '',
      to: '',
      subject: 'A new note is created',
      html: `
        <h1>New Note</h1>
        <p>A new note is created with the following details:</p>
        <p>
          Note Id: <br />
          ${notesId}
        </p>
        <p>
          Note Body: <br />
          ${body}
        </p>`
    }

    return transporter.sendMail(mailOptions)
      .then(() => console.log('Email Sent!'))
      .catch(error => console.error(error))
  })

Start by importing the nodemailer library.

Then, create a nodemailer transporter. The transporter is the object responsible for sending out the email. Nodemailer module supports SMTP based transport and other non-SMTP based transport. I will keep it simple, and use an SMTP transport for this Cloud Function.

For this to work, you need to create a new Nodemailer Transport using an SMTP account. I will be using the GMAIL SMTP account details. This is OK for testing locally but never used for production. Other options to use for production are: GMAIL OAUTH 2 and SMTP account you get from your hosting company.

Replace the user and pass fields with a real Gmail account.

Inside the Cloud Function, prepare a mailOptions object containing all the details of the email to send. Make sure to include the from, to, and the rest of the fields.

Finally, send the email by returning the transporter.sendMail(mailOptions) function call. This function returns a Promise.

That’s it! You can follow the steps above to test the function locally, using the Functions Shell.

Let’s deploy the Cloud Function to Firebase, and start receiving emails!

firebase deploy --only functions

The command above deploys all the Cloud Functions in your current app.

Now, whenever you create a new Note inside the app, the onNewNoteCreated() Cloud Function is triggered and eventually you receive an email similar to the one below:

Alt Text

Cloud Function Execution Process

Firebase internally manages the Server, and all the resources needed to deploy and run a Cloud Function. When a Cloud Function finishes executing, it needs to cleanup the resources used by the function.

How can Firebase tell or decide that now is the correct time to cleanup the resources, and that the Cloud Function has finished executing?

This task is certainly more complicated! Why?

Most of the Cloud Functions’ code you will be writing will interact with other Firebase SDKs, or even third party SDKs. This type of communication happens asynchronously.

A Cloud Function executes code, and returns immediately. However, there might be some kind of work that’s pending in the background, asynchronously. Therefore, Firebase cannot just run the function, and cleanup all the resources. It must wait until the function completely finishes running, and then do so.

For that reason, all of the Firebase SDKs support JavaScript Promises. What’s a JavaScript Promise?

A Promise represents some async work that should eventually complete! When work tracked by a Promise is still executing, the Promise is in a pending state. If the work completes successfully, the Promise is said to be fulfilled. If there is an error, the Promise becomes rejected.

These are the only states a Promise can go through. Once fulfilled or rejected, a Promise cannot go back to any other state.

For instance, the Firebase Admin SDK returns promises when your code: Reads or writes from a database. Interacts with files in the Cloud Storage. Sends a notification with Cloud Messaging.

Therefore, when dealing with Background-triggered Cloud Functions, it’s so important to just return the Firebase SDK API call you perform inside the Cloud Function. The Cloud Function Runner now has access to a Promise. As long as the Promise is in the pending state, it will wait, and will take no action. Once the Promise is fulfilled or rejected, it can safely remove all resources, and do the cleanup.

For an HTTPs-triggered Cloud Function, always make sure you return response.send() as the last line of the code. The Cloud Functions Runner will terminate and cleanup an HTTPs-triggered function only when the function returns a response to the client.

In this article, I’ve shown how to integrate and use a third party library, the Nodemailer. What we have implemented is a Background triggered function, hence we need to return a Promise at the end of the function. How are we doing so?

return transporter.sendMail(mailOptions)
      .then(() => console.log('Email Sent!'))
      .catch(error => console.error(error))
  })

The sendMail() function sends an email, and returns a Promise. In our case, we are sending an Email Sent! message to the logs when the Promise is fulfilled. Also, we are logging any errors when the Promise is rejected. At the same time, we are returning the sendMail() Promise to let the Cloud Functions Runner use that Promise to clean up the resources for this function. This only works because JavaScript Promises are chainnable!

Conclusion

For now, this will be the last episode on Fire the base of Vue.js! series.

Firebase is such a big topic, and requires many articles to cover it all. The team at Firebase did a great job at providing decent documentation. Still, I believe, working with the Firebase SDKs will give you experience and knowledge that theory cannot.

In the future, I might add episodes to this series. However, in the coming two weeks, I will start a new series on Vue.js development. Stay tuned!

Happy Vueing!

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

3 VueJS Component Libraries Perfect for Beginners cover image

3 VueJS Component Libraries Perfect for Beginners

For developers checking out VueJS for the first time, the initial steps are overwhelming, particularly when setting up projects from square one. But don’t worry! The VueJS ecosystem offers a plethora of remarkable component libraries, easing this early obstacle. These three libraries are pre-built toolkits, providing beginners with the means to kickstart their VueJS projects effortlessly. Let’s take a look! Quasar Quasar is among the most popular open-source component libraries for Vue.js, offering a comprehensive set of ready-to-use UI components and tools for building responsive web applications and websites. Designed with performance, flexibility, and ease of use in mind, Quasar provides developers with a wide range of customizable components, such as buttons, forms, dialogs, and layouts, along with built-in support for themes, internationalization, and accessibility. With its extensive documentation, active community support, and seamless integration with Vue CLI and Vuex, Quasar empowers developers to rapidly prototype and develop high-quality Vue.js applications for various platforms, including desktop, mobile, and PWA (Progressive Web Apps). PrimeVue PrimeVue is a popular Vue.js component library offering a wide range of customizable UI components designed for modern web applications. Developed by PrimeTek, it follows Material Design guidelines, ensuring responsiveness and accessibility across devices. With features like theming, internationalization, and advanced functionalities such as lazy loading and drag-and-drop, PrimeVue provides developers with the tools to create elegant and high-performing Vue.js applications efficiently. Supported by clear documentation, demos, and an active community, PrimeVue is an excellent choice for developers seeking to streamline their development process and deliver polished user experiences. Vuetify Vuetify is a powerful Vue.js component library that empowers developers to create elegant and responsive user interfaces with ease. Built according to Google's Material Design guidelines, Vuetify offers a vast collection of customizable UI components, ranging from buttons and cards to navigation bars and data tables. Its comprehensive set of features includes themes, typography, layout grids, and advanced components like dialogues and sliders, enabling developers to quickly build modern web applications that look and feel polished. With extensive documentation, active community support, and ongoing development, Vuetify remains a top choice for Vue.js developers seeking to streamline their workflow and deliver visually stunning user experiences. For newcomers venturing into Vue.js, the initial setup might seem daunting. Thankfully, Vue.js offers a variety of component libraries to simplify this process. Quasar, PrimeVue, and Vuetify are standout options, each providing pre-built tools to kickstart projects smoothly. Whether you prefer Quasar's extensive UI components, PrimeVue's Material Design-inspired features, or Vuetify's responsive interfaces, these libraries cater to diverse preferences and project requirements. With their clear documentation and active communities, these libraries empower developers to start Vue.js projects confidently and efficiently, enabling Vue developers to create polished user experiences....

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools cover image

Nuxt DevTools v1.0: Redefining the Developer Experience Beyond Conventional Tools

In the ever-evolving world of web development, Nuxt.js has taken a monumental leap with the launch of Nuxt DevTools v1.0. More than just a set of tools, it's a game-changer—a faithful companion for developers. This groundbreaking release, available for all Nuxt projects and being defaulted from Nuxt v3.8 onwards, marks the beginning of a new era in developer tools. It's designed to simplify our development journey, offering unparalleled transparency, performance, and ease of use. Join me as we explore how Nuxt DevTools v1.0 is set to revolutionize our workflow, making development faster and more efficient than ever. What makes Nuxt DevTools so unique? Alright, let's start delving into the features that make this tool so amazing and unique. There are a lot, so buckle up! In-App DevTools The first thing that caught my attention is that breaking away from traditional browser extensions, Nuxt DevTools v1.0 is seamlessly integrated within your Nuxt app. This ensures universal compatibility across browsers and devices, offering a more stable and consistent development experience. This setup also means the tools are readily available in the app, making your work more efficient. It's a smart move from the usual browser extensions, making it a notable highlight. To use it you just need to press Shift + Option + D (macOS) or Shift + Alt + D (Windows): With simple keystrokes, the Nuxt DevTools v1.0 springs to life directly within your app, ready for action. This integration eliminates the need to toggle between windows or panels, keeping your workflow streamlined and focused. The tools are not only easily accessible but also intelligently designed to enhance your productivity. Pages, Components, and Componsables View The Pages, Components, and Composables View in Nuxt DevTools v1.0 are a clear roadmap for your app. They help you understand how your app is built by simply showing its structure. It's like having a map that makes sense of your app's layout, making the complex parts of your code easier to understand. This is really helpful for new developers learning about the app and experienced developers working on big projects. Pages View lists all your app's pages, making it easier to move around and see how your site is structured. What's impressive is the live update capability. As you explore the DevTools, you can see the changes happening in real-time, giving you instant feedback on your app's behavior. Components View is like a detailed map of all the parts (components) your app uses, showing you how they connect and depend on each other. This helps you keep everything organized, especially in big projects. You can inspect components, change layouts, see their references, and filter them. By showcasing all the auto-imported composables, Nuxt DevTools provides a clear overview of the composables in use, including their source files. This feature brings much-needed clarity to managing composables within large projects. You can also see short descriptions and documentation links in some of them. Together, these features give you a clear picture of your app's layout and workings, simplifying navigation and management. Modules and Static Assets Management This aspect of the DevTools revolutionizes module management. It displays all registered modules, documentation, and repository links, making it easy to discover and install new modules from the community! This makes managing and expanding your app's capabilities more straightforward than ever. On the other hand, handling static assets like images and videos becomes a breeze. The tool allows you to preview and integrate these assets effortlessly within the DevTools environment. These features significantly enhance the ease and efficiency of managing your app's dynamic and static elements. The Runtime Config and Payload Editor The Runtime Config and Payload Editor in Nuxt DevTools make working with your app's settings and data straightforward. The Runtime Config lets you play with different configuration settings in real time, like adjusting settings on the fly and seeing the effects immediately. This is great for fine-tuning your app without guesswork. The Payload Editor is all about managing the data your app handles, especially data passed from server to client. It's like having a direct view and control over the data your app uses and displays. This tool is handy for seeing how changes in data impact your app, making it easier to understand and debug data-related issues. Open Graph Preview The Open Graph Preview in Nuxt DevTools is a feature I find incredibly handy and a real time-saver. It lets you see how your app will appear when shared on social media platforms. This tool is crucial for SEO and social media presence, as it previews the Open Graph tags (like images and descriptions) used when your app is shared. No more deploying first to check if everything looks right – you can now tweak and get instant feedback within the DevTools. This feature not only streamlines the process of optimizing for social media but also ensures your app makes the best possible first impression online. Timeline The Timeline feature in Nuxt DevTools is another standout tool. It lets you track when and how each part of your app (like composables) is called. This is different from typical performance tools because it focuses on the high-level aspects of your app, like navigation events and composable calls, giving you a more practical view of your app's operation. It's particularly useful for understanding the sequence and impact of events and actions in your app, making it easier to spot issues and optimize performance. This timeline view brings a new level of clarity to monitoring your app's behavior in real-time. Production Build Analyzer The Production Build Analyzer feature in Nuxt DevTools v1.0 is like a health check for your app. It looks at your app's final build and shows you how to make it better and faster. Think of it as a doctor for your app, pointing out areas that need improvement and helping you optimize performance. API Playground The API Playground in Nuxt DevTools v1.0 is like a sandbox where you can play and experiment with your app's APIs. It's a space where you can easily test and try out different things without affecting your main app. This makes it a great tool for trying out new ideas or checking how changes might work. Some other cool features Another amazing aspect of Nuxt DevTools is the embedded full-featured VS Code. It's like having your favorite code editor inside the DevTools, with all its powerful features and extensions. It's incredibly convenient for making quick edits or tweaks to your code. Then there's the Component Inspector. Think of it as your code's detective tool. It lets you easily pinpoint and understand which parts of your code are behind specific elements on your page. This makes identifying and editing components a breeze. And remember customization! Nuxt DevTools lets you tweak its UI to suit your style. This means you can set up the tools just how you like them, making your development environment more comfortable and tailored to your preferences. Conclusion In summary, Nuxt DevTools v1.0 marks a revolutionary step in web development, offering a comprehensive suite of features that elevate the entire development process. Features like live updates, easy navigation, and a user-friendly interface enrich the development experience. Each tool within Nuxt DevTools v1.0 is thoughtfully designed to simplify and enhance how developers build and manage their applications. In essence, Nuxt DevTools v1.0 is more than just a toolkit; it's a transformative companion for developers seeking to build high-quality web applications more efficiently and effectively. It represents the future of web development tools, setting new standards in developer experience and productivity....

Introducing the release of Vue 3 cover image

Introducing the release of Vue 3

Back in October 2018, Evan You announced plans to start building the third version of VueJS. Featuring 30+ RFCs, over 2,600 commits, 628 pull request from 99 contributors, Vue 3's release reflects tireless ingenuity, passion, and hard work. Its release, no doubt, is a cause for celebration for all of the Vue community members who have been eagerly awaiting it. I, for one, am thrilled to share some resources that I believe will help developers migrate to Vue 3: - Vue 2 -> Vue 3 Migration Guide - Vue Router 3.0 -> Vue Router 4.0 Migration Guide - Vuex 4 - Chrome Vue JS DevTools - FireFox DevTools Here at This Dot, we have tracked Vue 3's development from the onset. We have written blog posts, published a book, hosted Vue Meetups, debuted JavaScript Marathon, shared Modern Web Podcasts, and more! Today, we’ll take a guided tour through all the material we have shared on Vue 2 and Vue 3. Blog Posts Here are our latest blog posts on Vue 3: - How to Set Up Storybook in Vue 3 - Async Components in Vue 3 - Your first Vue 3 app using TypeScript - Teleporting in Vue 3 - Content Distribution in Vue 3 - Custom Directives in Vue 3 - Vue 3 Composition API, do you really need it? You may access the remaining blog posts at This Dot Labs Blog. A Complete Guide to VueJS In April 2020, This Dot released A Complete Guide to VueJS by Bilal Haidar. This book is a precise, and detailed resource for learning VueJS, and highlights some top courses for Vue and JavaScript. Most importantly, it gives a brief introduction to almost all the new features in Vue 3. Grab your own copy for free! Vue Meetups We have hosted more than 10+ Vue Meetups in the past year with dozens of speakers, including Evan You, other Vue Core team members, and Vue developers interested in the future of the framework. To watch past meetup recordings, follow this link to get access to all the meetups on one page. JavaScript Marathon This Dot's team delivered six free live Vue JS tutorials during the JavaScript Marathon. Here’s a list of all the VueJS live sessions recordings: - 1 Hour to Learn Vue - Master State Management in Vue with VueX - Master PWA in Vue - Learning Unit Testing in Vue - Pro Tips on Using AWS with Vue - Debugging Vue: Quick Tips and Tricks Modern Web Podcasts This Dot's team delivered more than 40+ podcasts in the last two years. Here’s a link to the Vue JS Podcasts: - S07E1 Modern Web Podcast - Introducing Vite - Evan You’s new project + Vue 3 Updates - S06E12 Modern Web Podcast - Vue 3, Code Education, & the Vue Community - S06E4 Modern Web Podcast - Vue Updates with Chris Fitz, Jake Dohm, and Rob Ocel The Future of Vue The team at This Dot is hardly finished tracking Vue's progress, as well as the progress of many other web based technologies. To join us on our technical exploration journey, be sure to follow This Dot Media on Twitter! If you have specific questions about how to begin your Vue 3 migration, or have general questions about Vue 3, don't hesitate to reach out to us at hi@thisdot.co....

The simplicity of deploying an MCP server on Vercel cover image

The simplicity of deploying an MCP server on Vercel

The current Model Context Protocol (MCP) spec is shifting developers toward lightweight, stateless servers that serve as tool providers for LLM agents. These MCP servers communicate over HTTP, with OAuth handled clientside. Vercel’s infrastructure makes it easy to iterate quickly and ship agentic AI tools without overhead. Example of Lightweight MCP Server Design At This Dot Labs, we built an MCP server that leverages the DocuSign Navigator API. The tools, like `get_agreements`, make a request to the DocuSign API to fetch data and then respond in an LLM-friendly way. ` Before the MCP can request anything, it needs to guide the client on how to kick off OAuth. This involves providing some MCP spec metadata API endpoints that include necessary information about where to obtain authorization tokens and what resources it can access. By understanding these details, the client can seamlessly initiate the OAuth process, ensuring secure and efficient data access. The Oauth flow begins when the user's LLM client makes a request without a valid auth token. In this case they’ll get a 401 response from our server with a WWW-Authenticate header, and then the client will leverage the metadata we exposed to discover the authorization server. Next, the OAuth flow kicks off directly with Docusign as directed by the metadata. Once the client has the token, it passes it in the Authorization header for tool requests to the API. ` This minimal set of API routes enables me to fetch Docusign Navigator data using natural language in my agent chat interface. Deployment Options I deployed this MCP server two different ways: as a Fastify backend and then by Vercel functions. Seeing how simple my Fastify MCP server was, and not really having a plan for deployment yet, I was eager to rewrite it for Vercel. The case for Vercel: * My own familiarity with Next.js API deployment * Fit for architecture * The extremely simple deployment process * Deploy previews (the eternal Vercel customer conversion feature, IMO) Previews of unfamiliar territory Did you know that the MCP spec doesn’t “just work” for use as ChatGPT tooling? Neither did I, and I had to experiment to prove out requirements that I was unfamiliar with. Part of moving fast for me was just deploying Vercel previews right out of the CLI so I could test my API as a Connector in ChatGPT. This was a great workflow for me, and invaluable for the team in code review. Stuff I’m Not Worried About Vercel’s mcp-handler package made setup effortless by abstracting away some of the complexity of implementing the MCP server. It gives you a drop-in way to define tools, setup https-streaming, and handle Oauth. By building on Vercel’s ecosystem, I can focus entirely on shipping my product without worrying about deployment, scaling, or server management. Everything just works. ` A Brief Case for MCP on Next.js Building an API without Next.js on Vercel is straightforward. Though, I’d be happy deploying this as a Next.js app, with the frontend features serving as the documentation, or the tools being a part of your website's agentic capabilities. Overall, this lowers the barrier to building any MCP you want for yourself, and I think that’s cool. Conclusion I'll avoid quoting Vercel documentation in this post. AI tooling is a critical component of this natural language UI, and we just want to ship. I declare Vercel is excellent for stateless MCP servers served over http....

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co