← Back to blog

Using @elianvancutsem/mostvisitedpages as a serverless function

I’ve moved from a regular RESTful API to serverless functions. Here is a little guide and explanation on why & how I did that.

So the @elianvancutsem/mostvisitedpages is a NPM package I wrote sometime ago to basically return your most visited pages fetched from Google Analytics.

At the time I wrote a complete API in NestJS with just a simple /analytics endpoint which would handle the Google Analytics part. (there were of course some other endpoints as well, but I won’t go deeper into them right now, maybe in the future…)


My main reasons for migrating to serverless functions instead of a full fetched container are

  1. no shared resources anymore
  2. code splitting / single responsibility
  3. better DX
  4. way, way faster
  5. Lower costs

I also migrated my website itself from Google Cloud Storage to Firebase hosting, which is basically the same functionality, but Firebase has the advantage of managing everything on a smaller interface.

That includes analytics, storage, functions, databases, authentication and hosting. All of those on one page with a quick overview. This is (speaking for myself here) a better developer experience.

Of course, if you’re in need of a bigger project, Google Cloud is still the way to go.


Now, one of the other reasons I wanted to migrate to serverless functions, is that my main website uses Astro. Astro has the option to fetch API’s at build-time instead of every page load. So for data that doesn’t change frequently, like your most visited pages, this is ideal. If you then only need to fetch a simple function instead of spinning up a whole container, you save on resources, time and money.

Sounds great no?

initiating functions

The functions I’m writing here, are all written in JavaScript (or TypeScript for that matter), but be aware that there are more function runtimes on Google Cloud (but not Firebase), like Go, Java or even PHP. (full list here)

You can setup a new functions project by running:

npm i -g firebase-tools

firebase init --functions

This will ask you some questions, like JavaScript or TypeScript, what project and so on.

If you’re not yet authenticated in firebase, run firebase login before initializing the functions.

Writing functions

Basically, each exported function from a file (like index.js), is deployed as a separate Firebase function.

import { HttpsFunction, https, Request, Response } from "firebase-functions";

export const yourFunction: HttpsFunction = https.onRequest(
  async (req: Request, res: Response) => {
    // our main code goes here

A little trick to manage more functions, without having them all in one file, is to do the following:

// analytics.js
export const analytics = https.onRequest(
  async (req: Request, res: Response) => {
    // analytics endpoint

// technologies.ts
export const technologies = https.onRequest(
  async (req: Request, res: Response) => {
    // technologies endpoint

// index.js
import { technologies } from "./technologies";
import { analytics } from "./analytics";

export { technologies, analytics };

These functions will get deployed as two separate Firebase functions.

Testing functions

Functions can be tested locally by running the npm run serve command.

This will spin up some local ports with your functions, logs and an emulator to manage and overview it all.

Really neat!

Deploying functions

firebase deploy --only functions

keep in mind that the --only functions here, is used to only deploy functions in case you have configured other firebase things, like storage, as well.

Till the next!

Written by Elian Van Cutsem

← Back to blog
  • Elians Astro Startkit

    Elians Astro Startkit

    I just published the setup I use for my personal projects. You can read more about it in this blogpost.

  • So, I'm leaving vBridge

    So, I'm leaving vBridge

    After spending a couple of years at vBridge Cloud, I'm leaving the company. I've worked at vBridge eversince I graduated. Now, It's time for a new adventure! I'm joining the DX-team at Astro full-time!

  • Becoming an Astro maintainer

    Becoming an Astro maintainer

    Since a week, I'm an Astro maintainer, in this post, I describe the process and my start in open source. I also give some insight in what I'm planning to work on.

  • 🍱 Brutal: A theme for Astro

    🍱 Brutal: A theme for Astro

    Brutal is a minimal neobrutalist theme for Astro. It's based on Neobrutalist Web Design, a movement that aims to create websites with a minimalistic and functional design. It has some integrations like Image Optimization, RSS, Sitemap, ready to get your SEO done right.

  • 🎤 Am I an international public speaker now?

    🎤 Am I an international public speaker now?

    A few weeks ago, I gave my first international keynote talk at JSWorld in Amsterdam. In this blogpost, I wanted to share some insights about the conference and my talk.

  • ✨ Building Blog tag index pages in Astro

    ✨ Building Blog tag index pages in Astro

    I wanted to add blog tag collection pages to my website. This way, people could filter on tags I used in my blog posts. Here is a guide on how I implemented it.