Setup Segment and Amplitude in Vue 3 (or React, Angular…)

Luka
7 min readFeb 10, 2022

📉 In this tutorial I wanted to document and share how to install Segment.io library in your Vue 3 application and send the events to Amplitude as a destination for Segment. I’ll show the setup for the Vue 3 SPA (single page application), but it should be easy to adapt it to your Angular or React app too.

Before we begin you have to create both Segment and Amplitude accounts. Come back after you log into both of those accounts…

Segment setup

In your newly created Segment account go to Sources and Add A New Source
- The source has to be Segment Javascript/Website
- Give it a label dev or prod (optional)
- Website URL has to be the http(s) URL of your website

Testing Segment locally

You’ll probably want to test the Segment installation before going to production. The problem is that Segment doesn’t allow testing using the localhost:// protocol/domain and the events coming from a local server don’t appear in the Segment degugger. Moreover, publishing your app on GitHub, Heroku won’t work either since these domains are public suffix domains and the Segment cookie cannot be set on them. You can read more about that issue here.

So, what we can do to circumvent the problem is to serve our site locally form a custom domain that we made up instead of using the default localhost://

To change the localhost to something that would work, we’ll have to add mylocaldomain.com into the etc/host where we’re basically telling our machine to forward any call we make to mylocaldomain.com to 127.0.0.1 (which is the IP address representing or machine). Here’s a tutorial on how to do that on a Mac/Linux or Win).

Once you’re done your etc/host will look something like this:

##
# Host Database
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
# Other IPs…
127.0.0.1 mycustomlocaldomain.com
# End of section

Next we have to change the default URL at which our NPM or YARN server serve our app. Change your vue.config.js (in the root of your Vue project) file and add this object to it:

devServer: {
host: ‘mycustomlocaldomain.com’
},

If you run yarn serve to spin up the local server you should see that your app is now running on http://mylocalhost.com:8080 and not localhost:8080

Ok, now all event that we fire within our app should flow and show up in Segment. Next, we have to do is to add Segment JS to our code.

First, navigate to the Overview tab for your newly created source in app.segment.com and copy the JS snippet

Paste that code in the <HEAD></HEAD> section of your index.html:

NOTE: Instead of serving Segment JS from a CDN we could probably install it as a JS package, but I I’ll use the Segment on all routes and I don’t want to bundle it into my code I’ll directly add it to my index.html.

If we run to start our app

yarn serve

and navigate to mycustomlocaldomain.com:8080 we should see our events being logged in Segment. Open the Debugger tab for your segment source and you should see the first events:

Since Vue app is a SPA these Page events will only fire when the page is first loaded or a user hits the refresh button. If we wanted we could give the event a name that is a bit more semantic 🤷🏻

Change your analytics.page() to analytics.page(“App Loaded or refreshed”)

Navigate to your “/” and you should see the App Loaded or refreshed event.

Navigating to the / of the app fires the event

If you navigate to another route of your app and hit the reload button the App Loaded or refreshed event should fire again

Reloading the app while on te /query-and-explorer path

Tracking navigation events in Vue

At this moment we’re only tracking the app load or reload events. What we want to track is navigation to any of the Vue routes declared in the router so that we can understand how and where our users navigate after they load the app.

There are many options here like setting up the callbacks in your router, but I opted for adding the logic of sending navigational events from my App.vue component that’s a parent component of all other componenes and in it I created a watcher that will pickup any route change and in it I call analytics.page(…) in order to log the navigation event

So, in my App.vue component I addd the following:

<script>  import AppHeader from ‘@/components/layout/AppHeader.vue’  import AppNavigation from ‘@/components/layout/AppNavigation.vue’  import { useRoute } from ‘vue-router’;  import { watch } from ‘vue’;  export default {     name: ‘App’,     components: {     AppHeader,     AppNavigation
},
setup() { const route = useRoute(); console.debug(`current route name on component setup init: ${route.name}`); watch(() => route.name, () => { console.debug(`MyCoolComponent — watch route.name changed to ${route.name}`); console.log(‘Route Name Changed: ‘+route.name) console.log(‘Route Params:’ ) console.dir(route.params) window.analytics.page(‘Visited ‘+route.name) }); return { route }; },}</script>

What this does is it fires a page event every time the app route updates. Now if you navigate around your app you should see something like this:

Navigation events being logged ;)

Tracking user action events in Vue

How Users navigate around the app tells us a lot, but it doesn’t tell us what they do once the route/section is loaded. We’re still missing the events such as user clicks, form submits, hover events, open/close dialog or whatever else we consider relevant for our data analysis.

In the user actions it important to “pickup” the context that is relevant in that moment for the event happening. For example, let’s say you’re covering an an e-commerce site with product analytics. You’d most probably have the button Add To Cart in many places (header, footer, inline) and on almost every page / screen of the app (Home, Prices etc.). You track each of those clicks as a separate event:

  • Clicked Add To Cart On The Homepage — header
  • Clicked Add To Cart On The Homepage — footer
  • Clicked Add To Cart On The Prices
  • Clicked Add To Cart On The Homepage

I’m not a big fan of so much noise. I personally consider all those events as a same action happening in a different context.

When a user can perform the same action in different sections, pages and context I like to send that context as properties of the event.

Here’s the code where I’m enriching my Event with some extra properties:

const handleButtonClick = ()=>{const analyticsProps = {pathName: router.currentRoute.value.name, path: router.currentRoute.value.path}console.log(“Clicked User Avatar” )console.dir(analyticsProps)window.analytics.track(‘Clicked User Avatar’, analyticsProps)}

Here’s the result

User was clicked on the Alerts section
User was clicked on the Homepage

User identification

I left this for the end, but you’ll most likely want to implement before anything else if your app has any type of authentication process before using it.

All the events we’ve seen so far belong to what is known as a anonymous user, but after a user logs into our app they’re not anonymous anymore and we should do something about it.

Setup Amplitude as a destination

In your Amplitude account Setup your data source. Go to import your data and then look for Segment as your source.

In Segment go to add destinations and setup your Amplitude (Actions) as your destination. Follow the guide…

You’ll need your Amplitude Public and Private key that you can obtain by entering Settings / Projects / YOURPROJECT

Copy those keys and if you load your app again you should see your first events travelling from your app to Segment and from there to Amplitude.

Here is how that looks like in Amplitude:

Conclusions

Here are some great resource that could help you with setting up your perfect product analytics stack :)

If you liked this post instead of thanking me you simply tell to the first person you see today that they look wonderful ❤️

--

--