Hotjar
Hotjar provides session recordings, heatmaps, and
on-page feedback for web products. This destination forwards walkerOS events to
Hotjar via the official
@hotjar/browser SDK,
translating events into Hotjar.event(...) calls and handling identity and
SPA state changes.
Hotjar is a web destination in the walkerOS flow:
Installation
npm install @walkeros/web-destination-hotjar- Integrated
- Bundled
import { startFlow } from '@walkeros/collector';
import { destinationHotjar } from '@walkeros/web-destination-hotjar';
await startFlow({
destinations: {
hotjar: {
code: destinationHotjar,
config: {
settings: {
siteId: 1234567,
},
},
},
},
});Add to your flow.json destinations:
"destinations": {
"hotjar": {
"package": "@walkeros/web-destination-hotjar",
"config": {
"settings": {
"siteId": 1234567
}
}
}
}Configuration
This destination uses the standard destination config wrapper (consent, data, env, id, ...). For the shared fields see destination configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
siteId | integer | Your Hotjar site ID (e.g. 1234567). Find it in your Hotjar dashboard under Settings. | |
hotjarVersion | integer | Hotjar snippet version. Defaults to 6 (current). Override only if Hotjar releases a new version. | |
debug | boolean | Enable Hotjar debug mode for development troubleshooting. | |
nonce | string | CSP nonce for the injected Hotjar script tag. Required when using strict Content-Security-Policy. | |
identify | any | walkerOS mapping value resolving to { userId, ...attributes } for Hotjar.identify(). userId is extracted as the first argument; remaining keys become user attributes. |
Mapping
Per-event rules under config.mapping. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
| Property | Type | Description | More |
|---|---|---|---|
identify | any | Per-event identity mapping. Resolves to { userId, ...attributes } -> Hotjar.identify(userId, attributes). | |
stateChange | any | SPA route change notification. Resolves to a relative path string -> Hotjar.stateChange(path). Used for accurate heatmaps on virtual page views. |
Examples
Combined features
A purchase fires Hotjar.identify then the renamed custom event in the canonical execution order.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "1a161f229138f8dc",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000106,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "completed_purchase",
"settings": {
"identify": {
"map": {
"userId": "user.id"
}
}
}
}hotjar.identify("us3r", {});
hotjar.event("completed_purchase")Default event
A walker event becomes a Hotjar.event call with the event name as the custom Hotjar event.
{
"name": "product view",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"detail",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [],
"consent": {
"functional": true
},
"id": "44a0082e7d9acb5b",
"trigger": "load",
"entity": "product",
"action": "view",
"timestamp": 1700000100,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}hotjar.event("product view")Destination identify
Destination-level identify calls Hotjar.identify with the user id on every push as Hotjar recommends.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "8204012b327b02a2",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000104,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}hotjar.identify("us3r", {});
hotjar.event("page view")State change
An SPA navigation fires Hotjar.stateChange with the new path instead of a Hotjar custom event.
{
"name": "page view",
"data": {
"domain": "www.example.com",
"title": "walkerOS documentation",
"referrer": "https://www.walkeros.io/",
"search": "?foo=bar",
"hash": "#hash",
"id": "/docs/"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"pagegroup": "docs"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "962a456ba5cc613a",
"trigger": "load",
"entity": "page",
"action": "view",
"timestamp": 1700000105,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"silent": true,
"settings": {
"stateChange": "data.id"
}
}hotjar.stateChange("/docs/")Renamed event
A mapping renames the event so the Hotjar custom event uses a canonical name like completed_purchase.
{
"name": "order complete",
"data": {
"id": "0rd3r1d",
"currency": "EUR",
"shipping": 5.22,
"taxes": 73.76,
"total": 555
},
"context": {
"shopping": [
"complete",
0
]
},
"globals": {
"pagegroup": "shop"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "product",
"data": {
"id": "ers",
"name": "Everyday Ruck Snack",
"color": "black",
"size": "l",
"price": 420
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "product",
"data": {
"id": "cc",
"name": "Cool Cap",
"size": "one size",
"price": 42
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
},
{
"entity": "gift",
"data": {
"name": "Surprise"
},
"context": {
"shopping": [
"complete",
0
]
},
"nested": []
}
],
"consent": {
"functional": true
},
"id": "4f3e39cd31d9696f",
"trigger": "load",
"entity": "order",
"action": "complete",
"timestamp": 1700000102,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"name": "completed_purchase"
}hotjar.event("completed_purchase")User login identify
A user login fires Hotjar.identify with userId and attributes before firing the event.
{
"name": "user login",
"data": {
"id": "u-123",
"email": "jane@example.com",
"plan": "premium"
},
"context": {
"dev": [
"test",
1
]
},
"globals": {
"lang": "elb"
},
"custom": {
"completely": "random"
},
"user": {
"id": "us3r",
"device": "c00k13",
"session": "s3ss10n"
},
"nested": [
{
"entity": "child",
"data": {
"is": "subordinated"
}
}
],
"consent": {
"functional": true
},
"id": "39eba92f7d7c00d2",
"trigger": "test",
"entity": "user",
"action": "login",
"timestamp": 1700000103,
"timing": 3.14,
"source": {
"count": 1,
"trace": "0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"type": "collector",
"schema": "4"
}
}{
"settings": {
"identify": {
"map": {
"userId": "data.id",
"email": "data.email",
"plan": "data.plan"
}
}
}
}hotjar.identify("u-123", {
"email": "jane@example.com",
"plan": "premium"
});
hotjar.event("user login")Consent
Hotjar has no runtime consent API. Consent is gated at the walkerOS level via
config.consent:
destinations: {
hotjar: {
code: destinationHotjar,
config: {
consent: { marketing: true },
settings: { siteId: 1234567 },
},
},
}Unconsented events are blocked by the collector before reaching the destination.