Integrating Session Replay

Capture, compress, and stream client sessions natively to your ANALAS server. Add the tracker directly to your website or import it in your SPA.

Option A: HTML Script Tag

Add this snippet in the <head> of your website to record sessions automatically:

<!-- Load the ANALAS Session Recorder -->
<script src="/session-recorder.js"></script>

<script>
  AnalasRecorder.init({
    apiKey: "your-workspace-api-key",
    sampleRate: 0.2,                // Record only 20% of sessions (0-1)
    maskAllText: true,              // Enable strict full-text masking
    excludePaths: ["/billing", "/settings"] // Skip tracking these routes
  });
</script>

Option B: JavaScript / SPA Import

For React, Next.js, or Single Page Apps, import and initialize the tracker inside your root layout or app wrapper:

import { initSessionRecorder } from "@/lib/session-recorder";
import { useEffect } from "react";

export default function RootProvider({ children }) {
  useEffect(() => {
    // Starts the recorder and returns a cleanup function
    const cleanup = initSessionRecorder({
      apiKey: "your-workspace-api-key",
      sampleRate: 0.5,              // Record 50% of sessions
      excludePaths: ["/admin"]      // Exclude paths
    });
    return cleanup;
  }, []);

  return children;
}

Contributing an insight type

Insight types are defined in src/lib/insight-types.ts as plain objects. Adding a new type takes three steps.

1. Register the type

Add an entry to the INSIGHT_TYPES array. Each entry must satisfy the InsightTypeDef interface:

interface InsightTypeDef {
  id: string;           // unique key, e.g. "funnel"
  label: string;        // shown in the type selector
  description: string;  // one-sentence explanation
  icon: string;         // emoji or single character
  configFields: {
    key: string;        // stored in queryConfig JSON
    label: string;
    placeholder: string;
  }[];
  docs?: Record<string, {
    description: string;   // Simple, non-technical explanation
    useCases: string[];    // Direct examples of when to use it
    fields: Record<string, string>; // Description of each configField key
  }>;
}

Example:

{
  id: "funnel",
  label: "Funnel",
  description: "Conversion rate between two events.",
  icon: "⬇",
  configFields: [
    { key: "fromEvent", label: "From event", placeholder: "page_view" },
    { key: "toEvent",   label: "To event",   placeholder: "user_signup" },
  ],
  docs: {
    en: {
      description: "Measures progression through sequence steps.",
      useCases: ["Tracking user checkout signup flow"],
      fields: {
        fromEvent: "The initial step event name",
        toEvent: "The target event name to reach"
      }
    },
    fa: {
      description: "سنجش میزان پیشرفت و تبدیل در مراحل مختلف.",
      useCases: ["ردیابی مراحل پرداخت و خرید کاربر"],
      fields: {
        fromEvent: "نام رویداد برای مرحله اول",
        toEvent: "نام رویداد هدف برای رسیدن به آن"
      }
    }
  }
}
Pro Tip: The insight creation modal is completely dynamic! Any fields you define in configFields will automatically generate input boxes in the UI, and their values will be saved to the database without any extra code.

2. Add the data query

Open src/app/api/workspace/[workspaceId]/insights/[insightId]/data/route.ts and add a branch for your type id. The route receives the insight's queryConfig (the values from your configFields) and the workspace's tenantId. Return:

// Required shape
{ total: number; rows: { day: string; count: number }[] }

// rows can be empty for non-time-series types

3. Render the card

Open src/app/workspace/[workspaceId]/insights/insight-card.tsx and add a render branch inside the card body:

{insight.type === "funnel" && (
  <FunnelRenderer data={data} />
)}

The card handles loading skeletons and error states for you — just focus on the visual.

Built-in types

#
Count
Total number of times an event occurred — all time, single number.
eventName
Trend
Event count over time.
eventNametimeFramedisplayType
Breakdown
Top values for a specific property (e.g. top pages, top browsers).
eventNameproperty
Comparison
Compare multiple event trends side-by-side.
eventNamestimeFramedisplayType
Funnel
Conversion progression through multiple steps.
eventStepsdistinctId
Metric
Advanced aggregations (average, unique count, percentiles).
eventNameaggregationpropertytimeFramedisplayType
Retention
Measure how often users return over time after a specific event.
startEventstartEventPropertystartEventValuereturnEventreturnEventPropertyreturnEventValuedistinctId