How to collect, store, and analyze clickstream data with Parseable

How to collect, store, and analyze clickstream data with Parseable

Clickstream consists of a series of ongoing user events (such as page visits, button clicks, form submissions, etc.) on websites or apps. These events capture a wealth of information about user behavior and site usability. Data-driven teams log these events, query, and sequence them to gain insights. Teams from marketing, product, and UI/UX departments use this data as a secret sauce to build delightful products.

However, the challenge lies in how to collect, store, and analyze this data so that teams can extract the specific metrics they need.

Why Parseable for specific, detailed reports of product usage

Choosing the best solution for analyzing your product and customer data depends on the volume of clickstream data generated and the metrics you want to measure.

If you have a low volume of data and want standard reports such as web traffic and page view reports, Google Analytics (GA) is a simple choice. However, if you need detailed, specific, and granular reports of product usage, you need raw event data—something that tools like GA fail to provide. GA gives you sampled, processed data, and rigid reports.

On the other hand, some product analytics tools may offer access to complete and unprocessed event data but have limited reporting capabilities compared to data analytics platforms. They often put limits on the number of data points you can log, have shorter default retention periods, and can become very expensive at large volumes.

Analytics platforms like Parseable offer limitless capabilities to harness clickstream data. You can use logging tools or built-in features of frontend libraries like React to capture these events and send data via simple HTTP requests. Parseable will collect all of the clickstream data (event data, metadata, and user-defined attributes) and store it in local or S3-compatible storage. This results in complete ownership of raw clickstream event data and a UI console to search, filter, and query the data any way you want.

Setting up a clickstream data pipeline with React and Parseable

Learn how to set up a clickstream data pipeline from your React app. We will use Axios to make XMLHttpRequests with the Parseable API from the browser and send these events to the Parseable instance. Parseable collects, stores, and queries clickstream data. You can store any volume of data, view it in table format from the console UI, apply filters, perform text searches, and write complex SQL queries.

Components of clickstream analytics

  • Data Source: React App with Axios. We will use a simple React app with a button on the homepage. Every time we click the button, we send the data of the click event along with metadata and user-defined attributes to the Parseable server via XMLHttpRequests.

  • Collection: Parseable will collect all of the payload data that we send to the Parseable server and store it in a defined stream. In Parseable, a stream is like a collection of data. You can choose to save the data on the local disk or any S3-compatible object storage. The schema of these streams is dynamic and need not be defined unless desired.

  • Analytics: Use the Parseable UI or CLI to query the stored data. The UI console offers a Live Tail feature to view the live stream of event data, a tabular view of clickstream data, a filter UI, and SQL for writing complex queries.

We will set up a basic React app as the data source to send us click event data.

  1. Set up Parseable.

  2. Create a stream (e.g. eventstream).

  3. Create a basic React app with a button.

  4. Create a custom Axios instance to send logs to Parseable.

  5. Implement Parseable Transport to send events, logs, and errors to the Parseable backend using the custom Axios instance.

  6. Create a click event listener.

  7. Add custom attributes to the button.

Installing Parseable

Create configuration secret

Open your terminal and type the command to create a new secret file:

cat << EOF > Parseable-env-secret
addr=0.0.0.0:8000
staging.dir=./staging
fs.dir=./data
username=admin
password=admin
EOF

Then create the secret in Kubernetes:

kubectl create ns parseable
kubectl create secret generic Parseable-env-secret --from-env-file=Parseable-env-secret -n parseable

Installing Parseable through Helm

helm repo add parseable https://charts.parseable.com
helm install parseable parseable/parseable -n parseable --set "parseable.local=false" --set "highAvailability.enabled=true"
kubectl port-forward svc/parseable 8000:80 -n parseable

Once you run the above command, Parseable is successfully installed and you can access it here: http://localhost:8000. The default username is admin and the password is admin. You can change these values in the secret file.

Finally, we need to create a log stream before we can send events. It is like a project that will store all your logs.

For this tutorial, we'll create a log stream named "eventstream." To create a log stream, log in to the Parseable instance and click the button on the right-hand, top side.

Log stream button

Once the log stream is created, let's write our custom Axios instance and Parseable transport to send clickstream data to Parseable.

Create a custom Axios instance to send logs to Parseable

import axios from "axios";

const parseableURL = "http://localhost:8000";
export const parseableAxiosInstance = axios.create({
  baseURL: parseableURL,
});

parseableAxiosInstance.interceptors.request.use(
  (config) => {
    if (config.method === "post" || config.method === "put") {
      let user = localStorage.getItem("profile");
      if (user) {
        user = JSON.parse(user);
        config.data = {
          ...config.data,
          user: user.id,
        };
      }
    }
    return config;
  },
  (error) => Promise.reject(error)
);

Set up transport to send events, logs, and errors to Parseable using the Axios instance

import { parseableAxiosInstance } from "../utils/axios-parseable-instance";
import { Buffer } from "buffer";

const username = "admin";
const password = "admin";
const basicAuth = "Basic " + Buffer.from(`${username}:${password}`).toString("base64");

export default class ParseableTransport {
  static event(info) {
    const streamName = "eventstream";
    const config = {
      method: "post",
      url: `/api/v1/logstream/${streamName}`,
      headers: {
        Authorization: basicAuth,
        "Content-Type": "application/json",
      },
      data: {
        timestamp: new Date(),
        ...info,
      },
    };

    parseableAxiosInstance(config)
      .then(function (response) {
        console.log(`Parseable logs sent with status code ${response.status}`);
      })
      .catch(function (error) {
        console.log("axios error", error);
      });
  }
}

Create a click event listener

const trackClick = (event) => {
  let target = event.target;

  while (target && !target.dataset.componentName) {
    target = target.parentElement;
  }

  let componentName = "NA";
  if (target) {
    componentName = target.dataset.componentName;
  }

  const { innerText, className } = event.target;
  ParseableTransport.event({
    event: "click",
    component: componentName,
    class: className,
    content: innerText,
    userAgent: navigator.userAgent,
    pathname: location.pathname,
    level: "info",
    message: `User clicked on ${componentName} component`,
  });
};

document.addEventListener("click", trackClick);

return () => {
  document.removeEventListener("click", trackClick);
};

Add attributes to the button

Finally, add any attribute you want to log on to that particular button by adding an attribute like below.

<button className="rounded-md" data-component-name="ClickSendButton">
  Click Me
</button>

Then you will see your clickstream data logged in the Parseable console. You can build queries and run them with the query builder and see the response in a table.

You may apply filters on each column or define complex conditions from the filter form. You may choose to keep a static or dynamic schema as you want.

Summary

Parseable enables you to collect, store, and query clickstream data in a powerful way. You can build metrics and custom reports using raw clickstream data with the Parseable UI.

Get total ownership of the data, complete freedom to define your own metrics, and no restrictions on the volume of data stored.