Skills hotjar

install
source · Clone the upstream repo
git clone https://github.com/TerminalSkills/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/hotjar" ~/.claude/skills/terminalskills-skills-hotjar && rm -rf "$T"
manifest: skills/hotjar/SKILL.md
safety · automated scan (low risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
  • references .env files
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content

Hotjar

Heatmaps, session recordings, and user feedback. See how users actually interact with your site and collect qualitative insights.

Script Installation

<!-- index.html — Add the Hotjar tracking script to your site.
     Place in <head> for heatmaps and recordings to capture from first paint. -->
<head>
  <script>
    (function(h,o,t,j,a,r){
        h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
        h._hjSettings={hjid:YOUR_SITE_ID,hjsv:6};
        a=o.getElementsByTagName('head')[0];
        r=o.createElement('script');r.async=1;
        r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
        a.appendChild(r);
    })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
  </script>
</head>

Next.js Integration

// components/hotjar.tsx — Add Hotjar to a Next.js App Router app.
// Uses next/script for optimal loading without blocking rendering.
'use client'
import Script from 'next/script'

export function HotjarScript({ siteId }: { siteId: number }) {
  return (
    <Script
      id="hotjar"
      strategy="afterInteractive"
      dangerouslySetInnerHTML={{
        __html: `
          (function(h,o,t,j,a,r){
            h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
            h._hjSettings={hjid:${siteId},hjsv:6};
            a=o.getElementsByTagName('head')[0];
            r=o.createElement('script');r.async=1;
            r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
            a.appendChild(r);
          })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
        `,
      }}
    />
  )
}
// app/layout.tsx — Include Hotjar in the root layout.
// Only loads in production to avoid polluting dev data.
import { HotjarScript } from '@/components/hotjar'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        {process.env.NODE_ENV === 'production' && (
          <HotjarScript siteId={Number(process.env.NEXT_PUBLIC_HOTJAR_SITE_ID)} />
        )}
      </body>
    </html>
  )
}

JavaScript API — Events and User Attributes

// lib/hotjar.ts — Hotjar JavaScript API helpers.
// Identify users, trigger events, and control recordings.
declare global {
  interface Window {
    hj: (...args: any[]) => void
  }
}

export function identifyHotjarUser(userId: string, attributes: Record<string, string | number | boolean>) {
  /**
   * Identify a user for filtering session recordings.
   * Attributes appear in the Hotjar dashboard for segmentation.
   * Max 100 attributes per user.
   */
  window.hj('identify', userId, attributes)
}

export function triggerHotjarEvent(eventName: string) {
  /**
   * Trigger a custom event. Use to:
   * - Start a recording on a specific user action
   * - Show a survey when a condition is met
   * - Tag recordings for filtering
   */
  window.hj('event', eventName)
}

export function tagRecording(...tags: string[]) {
  /**
   * Add tags to the current session recording.
   * Useful for filtering recordings by feature, experiment, or error state.
   */
  window.hj('tagRecording', tags)
}

export function triggerSurvey(surveyId: number) {
  /**
   * Manually trigger a Hotjar survey (bypasses page targeting rules).
   * Survey must be set to "API" trigger mode in the Hotjar dashboard.
   */
  window.hj('trigger', `survey_${surveyId}`)
}

export function setStateChange(url: string) {
  /**
   * Notify Hotjar of a virtual page change in an SPA.
   * Required for accurate heatmaps on client-side routed pages.
   */
  window.hj('stateChange', url)
}

SPA Route Change Tracking

// hooks/use-hotjar-spa.ts — Track route changes in React SPAs for Hotjar.
// Ensures heatmaps and recordings capture navigation in client-side routing.
'use client'
import { usePathname } from 'next/navigation'
import { useEffect } from 'react'

export function useHotjarSPA() {
  const pathname = usePathname()

  useEffect(() => {
    if (typeof window.hj === 'function') {
      window.hj('stateChange', pathname)
    }
  }, [pathname])
}

Privacy Controls

// lib/hotjar-privacy.ts — Configure Hotjar privacy and suppression.
// Control what gets captured in recordings and heatmaps.

/**
 * CSS classes for element-level control:
 *
 * data-hj-suppress     — Mask element text in recordings (shows asterisks)
 * data-hj-allow        — Explicitly allow capturing (overrides global suppress)
 * data-hj-masked       — Mask input field values
 *
 * HTML example:
 * <input type="email" data-hj-suppress />
 * <div data-hj-suppress>Sensitive content here</div>
 * <span data-hj-allow>Public content</span>
 */

export function configureSuppression() {
  // Suppress all input fields by default (opt-in to capture)
  // Set in Hotjar dashboard: Settings → Data Collection → Input masking
  // Or use CSS selectors to target specific elements

  // Programmatically suppress dynamic content
  const sensitiveElements = document.querySelectorAll('[data-sensitive]')
  sensitiveElements.forEach((el) => {
    el.setAttribute('data-hj-suppress', '')
  })
}

Integration with Google Analytics

// lib/hotjar-ga-integration.ts — Link Hotjar sessions with Google Analytics.
// Pass the GA client ID to Hotjar for cross-referencing sessions.
export function linkHotjarToGA() {
  // Wait for both GA and Hotjar to load
  const interval = setInterval(() => {
    if (typeof window.hj === 'function' && typeof window.gtag === 'function') {
      clearInterval(interval)

      // Get the GA client ID
      window.gtag('get', 'G-XXXXXXXXXX', 'client_id', (clientId: string) => {
        // Pass GA client ID as a Hotjar user attribute
        window.hj('identify', null, {
          ga_client_id: clientId,
        })
      })
    }
  }, 500)

  // Clean up after 10 seconds
  setTimeout(() => clearInterval(interval), 10000)
}

Survey API

// lib/hotjar-surveys.ts — Trigger Hotjar surveys based on user behavior.
// Combine with event tracking to show surveys at the right moment.

export function showNPSSurveyAfterPurchase() {
  /**
   * Trigger NPS survey after a successful purchase.
   * Survey configured in Hotjar dashboard with API trigger mode.
   */
  window.hj('trigger', 'post_purchase_nps')
}

export function showChurnSurvey() {
  /**
   * Show exit survey when user clicks cancel subscription.
   * Captures churn reason before they leave.
   */
  window.hj('trigger', 'churn_survey')
}

export function showFeatureFeedback(featureName: string) {
  /**
   * Collect feedback on a specific feature.
   * Tag the recording so you can watch sessions where feedback was given.
   */
  window.hj('tagRecording', [`feedback_${featureName}`])
  window.hj('trigger', 'feature_feedback')
}