A few weeks ago, Google Analytics broke on me for GuardianForge. Despite my best attempts, I haven’t been able to get it working even though I’ve followed every possible suggestion out there. So I asked around and someone on the Learn Build Teach discord recommended an alternative. That got me thinking “I bet there are a bunch of these services out there that do the same thing”. After exploring a few of the more cost-conscious options, I settled with PostHog and so far am pretty blown away by it.

Installation and setup

Installing the tool and setting it up was very straightforward. In my repo, I simply had to run the following command to install the library:

npm install posthog-js

Then I had to initialize the library with the following code somewhere in the repo:

import posthog from 'posthog-js'

posthog.init("POSTHOG_KEY", { api_host: 'https://app.posthog.com' };

Now in GuardianForge, I initialize everything in a Context file instead of in the default App.tsx. I do this so I can pull down a config.json file from S3, which loads all of the public keys and configuration variables. The reason I do that is so my Azure Pipeline that's used to build and deploy the code can perform a transformation on that file before it goes out, with the values updated for the environment the code is going to (QA or Production).

Here is how that code looks, or you can view the source on the GitHub repo.

posthog.init(config.posthogId, {
  api_host: 'https://app.posthog.com',
  capture_pageview: false,
  autocapture: false
})

You'll also notice that I have two additional configs set when initializing PostHog.

The capture_pageview being set to false prevents the library from trying to automatically detect when a page changes. This is disabled because GuardianForge is a React Single Page App, so there is technically no loading of pages when links are clicked, the JS just renders the updated DOM. To overcome this, I have a new  component that is in the Router.tsx file that can manually tell PostHog when a user navigates to another page.

function LocationHandler() {
  const { isInitDone } = useContext(GlobalContext)
  const location = useLocation()
  const [curr, setCurr] = useState("")

  useEffect(() => {
    const page_path = location.pathname + location.search
    if(isInitDone && curr !== page_path) {
      setCurr(page_path)
      posthog.capture('$pageview')
    }
  }, [location])
  return (<></>)
}

Additionally, with autocapture on, it was simply too noisy for what I needed it for. PostHog was trying to track every little detail the user was doing, such as clicking on buttons or typing into text fields. I don't need that level of detail, so that was turned off. Here's an example of what that looked like:

Things I like

First and foremost, the default dashboard is something I ACTUALLY understand! Don't get me wrong, I think Google Analytics is a powerful tool when you have the correct understanding of the setup and terminology. I predominantly want to focus on building GuardianForge over learning how to slice and dice metrics, at least for now. Here is an example of the dashboard:

Another thing I like is the ability to identify users with your own values. I'm not doing it in any kind of creepy way, but only for my own knowledge to match Destiny users to metrics on how they use the app. I'm hoping at some point I can identify power users to work more closely with and understand what features would be best to implement. Here is the code I'm using to tie users into PostHog:

posthog.identify(authData.membership_id)

And then I can see them in the PostHog app and see what features they are using. This is my record in the QA environment, and the number is actually my unique ID in Destiny (nothing you couldn't get by searching on the forums and analyzing network traffic):

Things I plan to explore more

Since PostHog makes it easy to create custom events with custom data, I plan to expand on this to see what kinds of builds people are making without having to dive into the database. I also want to explore Annotations more, which are ways that I can tie external events to PostHog, and see if those actions (say, sharing a build on Twitter) have a positive effect on the usage of GuardianForge.