Stickybeak Docs Dashboard Get early access

Frameworks

Angular

Angular analytics with Stickybeak starts by adding its script to your rendered pages; this guide shows you where it belongs and how to track page views, goals and purchase revenue. It is a lighter alternative to Google Analytics for Angular, with live visitors, goals and revenue attribution in one script.

Add the script

  1. Copy your snippet

    In Stickybeak, open Settings, pick your site and copy the HTML snippet.

  2. Paste it into src/index.html

    Put it before </head>.

    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>My app</title>
        <base href="/" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <script
          defer
          data-site="YOUR_SITE_ID"
          data-domain="example.com"
          src="https://app.usestickybeak.com/_cfw/s.js"
        ></script>
      </head>
      <body>
        <app-root></app-root>
      </body>
    </html>

    Angular copies tags in index.html into the built page as they are.

  3. Build and deploy

    ng serve runs on localhost, where the script switches itself off, so development isn't counted.

Only in production builds

To keep staging builds out too, give production its own index file. Copy src/index.html to src/index.prod.html, keep the snippet only in the copy, and point the production configuration at it in angular.json:

"configurations": {
  "production": {
    "index": {
      "input": "src/index.prod.html",
      "output": "index.html"
    }
  }
}

That block goes under projects → your-app → architect → build.

Check it's working

Test the deployed site, then verify your install.

Track goals

Add data-goal to rendered links or buttons. For other events, use the typed queued helper below. See Custom goals.

<a routerLink="/signup" data-goal="start_signup" data-goal-plan="pro">Start free trial</a>
type GoalProps = Record<string, string | number | boolean>;
type Stickybeak = ((goal: string, props?: GoalProps) => void) & { q?: unknown[][] };

declare global {
  interface Window {
    stickybeak?: Stickybeak;
  }
}

export function track(goal: string, props?: GoalProps): void {
  if (typeof window === "undefined") return; // on the server: nothing to do
  if (!window.stickybeak) {
    // Hold calls made before the script loads; it sends them when it arrives.
    const queue: Stickybeak = (...args) => {
      (queue.q ??= []).push(args);
    };
    window.stickybeak = queue;
  }
  window.stickybeak(goal, props);
}
import { Component } from "@angular/core";
import { track } from "./stickybeak";

@Component({
  selector: "app-upgrade-button",
  template: `<button type="button" (click)="upgrade()">Upgrade to Pro</button>`,
})
export class UpgradeButtonComponent {
  upgrade() {
    track("upgrade_click", { plan: "pro" });
  }
}

Track purchases

After confirming an order in the browser, send:

window.stickybeak?.("purchase", { revenue: 49, currency: "USD", order_id: "ORDER_ID" });

Use real values; see Revenue.

Page changes

History routes count new paths. replaceUrl, query-only, fragment-only and hash-location changes do not. See Single-page apps.

If it isn't working

Check the production site ID and domain, then see Troubleshooting.