Track Live Website Visitors Without Subscriptions

A client wanted to see who was on their website in real time.

They liked the Tidio widget but did not want to pay for a subscription.

The challenge had two parts:

  • The site used WordPress on different hosting.
  • I could not add Firebase directly to the WordPress setup.

I built an external tracker using Firebase. Here is how it works.

The Solution

I used a single script tag in the WordPress header. This script connects to an independent Firebase project.

• Live Presence: I used Firebase Realtime Database with the onDisconnect() function. This automatically removes a user from the "online" list when they close their tab or lose connection. • Visitor History: I used a Netlify Function to write data to Firestore. This allows for server-side IP geolocation. • Security: I used anonymous authentication. Visitors can only write to their own session node. Only the admin can read the full list.

The Tricky Bugs

Building this was not smooth. I ran into three major technical hurdles.

  1. The Caching Trap The history showed zero sessions. I found out the tracker script had a one-year cache policy. Visitors were stuck using an old version of the script.
  • Fix: I set a five-minute cache policy for the tracker script.
  1. The Fake CORS Error The browser reported a CORS error. I thought I had a domain whitelist issue. A simple curl test showed the server worked fine. The truth was different. The server was actually crashing. In Node.js, if you use a 204 status code, you cannot use an empty string as a body. You must use null. The empty string caused a crash before the CORS headers could be sent. The browser saw no headers and assumed it was a CORS problem.
  • Fix: Changed the response body from '' to null.
  1. The Missing Data Gap Filters for "Today" or "Last 7 Days" returned nothing. Some users showed "Unknown" locations. This happened because I only calculated the timestamp and location on the very first page load. If a user had an old session in their browser, the server missed the "start" event.
  • Fix: I made the calculation idempotent. Now the script recomputes these values on every event.

Key Takeaways

• A CORS error in the browser is not always a configuration issue. It can hide a server crash. Always check your server logs. • A curl POST test does not test a browser. Browsers send an OPTIONS preflight request first. Your test must include this to be valid. • Use null for "no content" HTTP statuses like 204. Do not use empty strings.

Source: https://dev.to/androve2k/whos-online-on-the-site-without-tidio-live-presence-and-visitor-history-with-firebase-37il