Loading tutorials…
Loading tutorials…
GA4 tells you what happened across thousands of sessions. Hotjar shows you why for 5 of them. Connecting the two means you can click from a GA4 anomaly straight into the 5 Hotjar recordings that explain it. This is the workflow.
Who this is forTeams running both Hotjar and GA4 who haven't yet connected them. If you're reading this and Hotjar lives in a tab separate from GA4 in your workflow, you're leaving the highest-value integration in your stack on the table.
What you'll need
Step 1
Hotjar Plus+ has a native one-click GA4 integration. It pushes a custom dimension (hotjar_session_url) into GA4 so you can click from any GA4 session report into the matching Hotjar recording.
Open Hotjar → Settings → Sites & Organizations → click your site → Integrations.
Find Google Analytics 4 in the integrations list. Click Connect.
Sign in with the Google account that has Edit access to your GA4 property. Authorize Hotjar to push data into a custom dimension.
Pick your GA4 property and Web data stream. Hotjar will create a User-scoped custom dimension named "hotjar_session_url" by default — leave the name as default unless you have a conflicting dimension.
Confirm. From this point on, every GA4 session captured will have a hotjar_session_url parameter populated with the URL of the matching Hotjar recording (if Hotjar captured it — subject to your sampling plan).
Wait 24-48 hours for the integration to start populating GA4 with linked recordings. Standard GA4 latency applies — don't expect immediate data.
Step 2
Open GA4 Explorations → create a free-form exploration → add hotjar_session_url as a dimension. Each row should have a clickable URL.
In GA4 → Explore → Blank → create a new exploration.
Add hotjar_session_url to Dimensions. Add Session ID or User ID to Dimensions. Add Sessions to Metrics.
Pick a recent date range (last 7 days). Run the exploration.
You should see rows with: Session ID, hotjar_session_url (a URL starting with insights.hotjar.com/sites/...), and a session count of 1.
Click any hotjar_session_url. It should open the Hotjar recording for that session directly. If the link is blank or "(not set)" for most rows, the integration isn't pushing data — re-check the connection.
If clicking the link returns a 404 or "Recording not found," the Hotjar session was either deleted (retention expired) or wasn't captured (sampling). Both are normal — Hotjar only links sessions it actually recorded.
Step 3
This is the joint workflow. Find a metric anomaly in GA4 → filter to the affected sessions → click into the Hotjar recordings for those sessions.
Open GA4 → Reports → Engagement → Pages and Screens. Sort by Bounce Rate descending or Conversion Rate ascending. Spot a page with anomalous behavior.
Open GA4 → Explore → free-form exploration. Filter to that page + the anomaly condition (e.g., page = /pricing AND conversion_rate < 1%).
Add hotjar_session_url as a dimension. The output is a list of GA4 sessions for the anomalous segment, each with a clickable Hotjar recording link.
Click into 5 recordings. Watch each at 2x. Patterns emerge — usually within the first 2 recordings.
Example workflow: GA4 shows a 30% drop in /checkout/payment conversion this week → filter to that page + last 7 days + did_not_convert → click into 5 Hotjar recordings → discover users are hitting a JavaScript error on the Stripe form. Fix shipped same day.
Without the integration, this workflow takes hours of manual session matching. With it, 5 minutes.
Step 4
If you push internal user IDs to GA4 (for logged-in users), also push them to Hotjar via hj("identify"). This unlocks two-way joins.
If your site has logged-in users, you already push their internal user ID to GA4 via gtag('config', 'G-XXXX', { user_id: 'internal_id' }).
Push the same internal ID to Hotjar: hj("identify", "internal_id", { plan: "premium", signup_date: "2026-01-15" }) on every page load for logged-in users.
Now: GA4 sessions for a specific user can be filtered AND Hotjar recordings for the same user can be filtered. Both tools see the same identifier.
Use case: a customer reports a bug. You pull their GA4 sessions to find the timing. Then pull their Hotjar recordings to see what they actually did. Two evidence sources, same user, no manual stitching.
GDPR note: pass internal IDs only — never email or other PII. See the GDPR troubleshooting tutorial.
Step 5
Identify 3-5 user cohorts that matter, save them as filters in both tools. "Cart abandoners," "paid-traffic non-converters," "mobile checkout drop-offs" — same names in both.
Pick 3-5 cohorts based on your business: (1) Paid-traffic non-converters, (2) Cart abandoners, (3) Mobile checkout drop-offs, (4) High-LTV trial users, (5) Multi-session researchers who haven't bought.
In GA4: build each cohort as a saved Audience (Admin → Audiences). Audiences appear as Comparisons in Reports and as Filters in Explorations.
In Hotjar: build the matching cohort as a saved Recordings filter. Use the same name (e.g., "Cart abandoners — mobile") in both tools.
Now your CRO meeting is: open GA4 → pull cohort metrics for the week → open Hotjar with the same cohort filter → watch the recordings → write findings.
After 4 weeks, you'll have 12-20 findings tied to specific cohorts. Group by cohort to see which audience needs which fix. This is what separates a CRO practice from a tool subscription.
Step 6
Use GA4 Custom Insights to alert on metric anomalies. Use Hotjar alerts to flag rage-click spikes. Route both to the same Slack channel.
GA4 alerts: Admin → Custom Insights → Create. Example: "Alert me if conversion rate drops by 30% week-over-week." Routes to email by default; can webhook to Slack via Make/Zapier.
Hotjar alerts (Business+): in a heatmap or recording filter, click Alerts. Example: "Alert me if rage clicks on /checkout/payment exceed 10 in any 24-hour window."
Route both to the same Slack channel (#cro-alerts or similar). Now your team sees GA4 + Hotjar signals in one place.
When an alert fires: GA4 alert → check the corresponding Hotjar recordings (via the integrated dimension). Hotjar alert → check GA4 to see if the issue is statistically real or just a few outliers.
Don't over-alert. 2-3 GA4 alerts + 2-3 Hotjar alerts on top conversion paths is plenty. More than that is noise that gets muted.
Step 7
Run the joint workflow for 30 days. At the end, count findings shipped and impact. If you can't name 3+ shipped CRO fixes from the workflow, something is off.
For 30 days, run the joint workflow weekly: GA4 anomaly check → Hotjar recording review → ship 1 fix.
At day 30, audit: how many findings did you write down? How many shipped? What was the conversion-rate movement on the pages you touched?
Baseline expectations: 3-5 written findings/week, 1 shipped fix/week, 5-15% conversion lift on touched pages within 90 days.
If you're writing findings but not shipping: bottleneck is engineering bandwidth. Prioritize lower-effort fixes (copy changes, button styling) over higher-effort ones (form redesigns) to maintain shipping velocity.
If you're shipping but not seeing conversion lift: the findings are noise. Spend more time validating with recordings before committing to fixes. n=1 recording isn't a finding; n=5+ with the same pattern is.
If the joint workflow isn't producing — stop. Either commit a specialist to run it for you, or scale back to a single tool. Two tools running half-used is worse than one tool fully used.
Common mistakes
Setting up the integration but never using it
What goes wrong: Integration is connected. hotjar_session_url shows up in GA4. No one ever pulls an exploration with it. Hotjar and GA4 continue to live in separate tabs in separate workflows. ~$50-300/mo on Hotjar producing no leveraged insight.
How to avoid: Calendar a recurring 30-min/week joint review. Pull a GA4 anomaly. Click into 5 Hotjar recordings. Write findings. The cadence is the practice — not the integration setup.
Custom dimension not registered in GA4
What goes wrong: Hotjar pushes the dimension via API but GA4 reports show "(not set)" because the dimension wasn't explicitly registered in Admin → Custom Definitions. Team thinks the integration is broken; spends hours debugging. It just needed a one-time registration click. Typical cost: 4-8 hours of dev time ($500-1,500) chasing a phantom bug.
How to avoid: After connecting Hotjar to GA4, go to GA4 → Admin → Custom Definitions → Custom Dimensions. Confirm hotjar_session_url is registered as User-scoped. If not, click Create custom dimension and add it manually.
Pushing different user IDs to GA4 vs Hotjar
What goes wrong: GA4 sees user_id = '12345'. Hotjar sees user_id = 'user_12345'. Can't join on user. The two evidence sources stay siloed. The single most valuable workflow (combining quant + qual for one user) is broken. Cost: you keep paying for both tools ($30-200/mo Hotjar + GA4 dev time = $5K-15K/year of value) but capture only 50% of the combined leverage.
How to avoid: Standardize the internal user ID format. Use the same string in both gtag("config", { user_id }) and hj("identify", userId). Document it in your tracking spec.
Routing GA4 alerts and Hotjar alerts to different places
What goes wrong: GA4 alerts go to one email; Hotjar alerts go to another Slack channel. Team doesn't see both signals together. A GA4 drop and a Hotjar rage-click spike both fire same morning — but no one connects them because the alerts are in different inboxes. A critical bug that should be caught in 24 hours instead takes 5-10 days to diagnose — costing $3,000-12,000 in conversions lost during the diagnosis window.
How to avoid: Route both to the same Slack channel. #cro-alerts or similar. Team sees GA4 + Hotjar signals together; faster diagnosis.
Treating the integration as automatic CRO
What goes wrong: Team installs the integration, expects "insights" to materialize. None do — because integrations connect data, they don't analyze it. After 2 months of no findings, team concludes "the tools don't work" and downgrades plans. Net cost: $300-2,000 in subscription dollars spent during the silent period, plus the 2-3 months of CRO momentum lost.
How to avoid: The integration enables the workflow; the workflow is a recurring human practice. Calendar a 30-min/week joint review. Watch recordings. Write findings. Ship fixes. The tools are passive without the practice.
Recap
Done — what's next
How to set up a Hotjar account from scratch
Read the next tutorial
Hand it off
The Hotjar + GA4 integration is one of the highest-leverage workflows in CRO — but only if you run it as a recurring practice. Most teams set it up and never use it. A vetted CRO specialist on EverestX runs the joint review weekly and ships 1-2 fixes per week per account. Typical engagement: $400-1,000/mo at $14-16/hr.
See specialist rates
Most common cause: the custom dimension wasn't registered in GA4 → Admin → Custom Definitions. Hotjar pushes the dimension via API but GA4 requires explicit registration to show it in reports. Other causes: only 24-48 hours have passed since connection (GA4 latency), or Hotjar isn't capturing those sessions (sampling).
Not directly. The native integration is one-way (Hotjar → GA4). If you want Hotjar Events to mirror GA4 Events, the standard pattern is dataLayer.push() from your app → GTM fires both Hotjar event and GA4 event in parallel. The dataLayer is the source of truth.
No. The native GA4 integration is gated to Hotjar Plus and above. On Free Basic, the workaround is manual: filter recordings in Hotjar by date + URL, find a matching GA4 session by timestamp + page, link manually. Tedious but possible. Plus tier removes the friction.
Yes, in parallel. The standard pattern is to install the Hotjar snippet via GTM (cleaner than direct <head>), AND enable the native Hotjar → GA4 integration for the recording-link workflow. GTM handles the tag firing; GA4 integration handles the data join.
Both identify a logged-in user across sessions, but they're separate systems. hj("identify") tells Hotjar who the user is — unlocks user-attribute filters in recordings, funnels, and surveys. GA4's user_id tells GA4 — unlocks cross-device session tracking in reports. Push the same internal ID to both for two-way joins.
Negligibly. The integration is server-side metadata routing once Hotjar has captured the session — adds no client-side payload. Page load times are identical pre- and post-integration. The only performance consideration is that running both Hotjar and GA4 adds 60-100KB of JS — that's standard, not integration-specific.
Hotjar
Hotjar isn't hard to install — it's hard to install in a way that won't burn through your monthly session quota in week one. This is the setup that prevents the rebuild most teams do at month two.
Hotjar
Hotjar's recordings are the most powerful feature in the tool — and the most-wasted. The difference is filter discipline. This is the setup that turns 1,000 recordings/week into 5 useful insights, not 1,000 hours of "someday I'll watch these."
Hotjar
GA4 tells you 60% of users abandoned at checkout step 2. Hotjar Funnels tells you which 60% — and lets you click straight into 5 recordings of the people who dropped off. That's the workflow.
Google Analytics 4
GA4 isn't hard to install — it's hard to install *correctly* so the data is actually usable six months from now. This is the walkthrough that prevents the rebuild most owners do at month four.