# NPM package (@metricraven/web)

> Install MetricRaven from npm in Next.js, React, Vue or Svelte, with typed track, identify, pageview and consent calls.

Source: https://metricraven.com/docs/npm-package  
Markdown: https://metricraven.com/docs/npm-package.md  
Section: Installation guides

`@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**

   ```bash
   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.

   ```typescript title="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.

   ```typescript
   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

```typescript
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
});
```

| Option | What it does |
| --- | --- |
| siteId | Required. Your site ID from Settings. |
| apiHost | Where MetricRaven is served. Defaults to https://metricraven.com. |
| scriptUrl / endpoint | Same-origin proxy paths for the script and for events. See the proxy guide. |
| autoPageviews | Defaults to true: records the first page and history navigation. Set false to call pageview() yourself. |
| hashRouting | true counts #/route and #!/route as paths; "all" also counts plain #anchors such as #pricing. |
| stripQuery | Drops query strings from recorded URLs. |
| consent | Set true when your cookie banner already has stored consent. Otherwise nothing is stored in the browser. |
| domain | Shares the consented visitor cookie across a domain and its subdomains. |
| allowLocalhost | Also tracks on localhost and \*.test. |
| nonce | CSP nonce for the injected script tag. |
| allowedHostnames | Your site's other domains, e.g. ["app.example.io"]. Links and forms to them keep the same visitor (cross-domain tracking). |
| debug | Logs to the console what is sent and why anything is skipped. |

## Functions

| Function | Notes |
| --- | --- |
| 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

```typescript title="Vue / Nuxt"
// main.ts (Vue / Nuxt client plugin)
import { init } from "@metricraven/web";
init({ siteId: import.meta.env.VITE_METRICRAVEN_SITE_ID });
```

```html title="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](https://metricraven.com/docs/spa-virtual-pages).
- Landing site and app on different domains? Pass `allowedHostnames` and use `linkUrl` for navigation in code. See [Cross-domain tracking](https://metricraven.com/docs/cross-domain).

## 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](https://metricraven.com/docs/proxy).
- For identify rules and limits, see [Link users to visits](https://metricraven.com/docs/identify-users). For consent, see [Consent & visitor IDs](https://metricraven.com/docs/consent).
