Sign up

Installation guides

NPM package (@metricraven/web)

On this page

@metricraven/web loads the MetricRaven tracker for you and gives you typed functions to call it. It has no dependencies and is safe to import during server rendering.

The package loads the same hosted script as the HTML tag, with the options you pass. So consent rules, single-page app routing and the data it sends are the same either way. Use the package or the tag, not both. If the tag is already on the page, the package uses it instead of loading a second copy.

Install

  1. Add the package

    terminal
    npm install @metricraven/web
  2. Call init once, in the browser

    Call init from client code that runs once, such as a root layout effect. Calling it again does nothing. On the server, every function does nothing.

    Next.js App Router
    // app/analytics.tsx
    "use client";
    import { useEffect } from "react";
    import { init } from "@metricraven/web";
    
    export function Analytics() {
      useEffect(() => {
        init({ siteId: process.env.NEXT_PUBLIC_METRICRAVEN_SITE_ID! });
      }, []);
      return null;
    }
    
    // app/layout.tsx: render <Analytics /> once inside <body>.
  3. Track events and identify users

    You can import these anywhere, even before init. Calls made before the script loads are queued and sent in order.

    server.ts
    import { track, identify, pageview, setConsent, reset, getVisitorId } from "@metricraven/web";
    
    track("checkout_started", { plan: "pro" });
    identify(user.id, { name: user.name, email: user.email, plan: "pro" });
    pageview("/checkout/payment"); // a virtual screen; with autoPageviews: false, every view
    setConsent(true); // from your cookie banner
    reset(); // on logout
    const visitorId = getVisitorId(); // null until the first response

Verify it works

Deploy and open your site. Within a few seconds, the visit appears in Realtime. On localhost, pass allowLocalhost: true to test locally.

Options

server.ts
init({
  siteId: "YOUR_SITE_ID",
  apiHost: "https://metricraven.com", // where MetricRaven is served
  scriptUrl: "/a/script",              // or: a same-origin proxy path for the script…
  endpoint: "/a/event",                // …and for events
  autoPageviews: true,                 // false: call pageview() yourself
  hashRouting: false,                  // true: count #/route paths; "all": also #anchors
  stripQuery: false,
  consent: false,                      // true when your banner already has consent
  domain: "example.com",               // share the consented cookie across subdomains
  allowedHostnames: ["app.example.io"], // your other domains: keep the same visitor across them
  allowLocalhost: false,
  debug: false,                        // true: log what is sent to the console
});
OptionWhat it does
siteIdRequired. Your site ID from Settings.
apiHostWhere MetricRaven is served. Defaults to https://metricraven.com.
scriptUrl / endpointSame-origin proxy paths for the script and for events. See the proxy guide.
autoPageviewsDefaults to true: records the first page and history navigation. Set false to call pageview() yourself.
hashRoutingtrue counts #/route and #!/route as paths; "all" also counts plain #anchors such as #pricing.
stripQueryDrops query strings from recorded URLs.
consentSet true when your cookie banner already has stored consent. Otherwise nothing is stored in the browser.
domainShares the consented visitor cookie across a domain and its subdomains.
allowLocalhostAlso tracks on localhost and *.test.
nonceCSP nonce for the injected script tag.
allowedHostnamesYour site's other domains, e.g. ["app.example.io"]. Links and forms to them keep the same visitor (cross-domain tracking).
debugLogs to the console what is sent and why anything is skipped.

Functions

FunctionNotes
init(options)Loads the tracker once and returns the client. Does nothing on the server.
track(name, props?)A custom goal. Names start with a letter. Up to 10 properties.
identify(userId, traits?)Links this visitor to your user ID, with optional name, email, image (https profile picture) and custom traits.
payment({ email })On the page after a successful payment: this visitor paid with this email. A provider payment with that customer email, within an hour and linked to nothing else, is credited to this visit. See Attribute by email.
pageview(path?)A manual view: the current URL, or a same-origin virtual path such as /checkout/payment.
setConsent(granted)Grants or withdraws analytics storage consent from your cookie banner.
reset()On logout. Forgets identify state and, with consent, starts a new visitor ID.
getVisitorId()The current visitor ID. Returns null until the first response, and on the server.
linkUrl(url)The URL with a short-lived cross-domain token added when it leads to one of allowedHostnames; otherwise unchanged. For navigation in code.
linkParams()The cross-domain parameters ({ mr_link }) to append yourself, or {} without a fresh token.
onVisitorId(listener)Called when the visitor ID changes. Returns an unsubscribe function.
ready()Resolves once the script has loaded, or failed to load (for example, blocked).

Other frameworks

Vue / Nuxt
// main.ts (Vue / Nuxt client plugin)
import { init } from "@metricraven/web";
init({ siteId: import.meta.env.VITE_METRICRAVEN_SITE_ID });
SvelteKit
<!-- src/routes/+layout.svelte -->
<script>
  import { onMount } from "svelte";
  import { init } from "@metricraven/web";
  onMount(() => init({ siteId: import.meta.env.PUBLIC_METRICRAVEN_SITE_ID }));
</script>
<slot />
  • React (Vite): call init in main.tsx before rendering.
  • Routers that use the history API are tracked automatically. For hash routers, pass hashRouting: true. See SPA & virtual pages.
  • Landing site and app on different domains? Pass allowedHostnames and use linkUrl for navigation in code. See Cross-domain tracking.

Details

  • The package is ESM and CommonJS, with TypeScript types. Nothing runs when you import it, so it's tree-shakeable and safe in server components and route handlers. Tracking itself only happens in the browser.
  • If an ad blocker or CSP blocks the script, calls keep queueing quietly and never throw. To avoid blockers, see Proxy.
  • For identify rules and limits, see Link users to visits. For consent, see Consent & visitor IDs.