SaaS Implementation Guide
To track a SaaS product with Sealmetrics, add the tracking script to your marketing site and app, then instrument three event types: pageviews (automatic, for pricing and feature pages), microconversions via sealmetrics.micro() (plan selection, signup steps, onboarding, feature usage) and conversions via sealmetrics.conv() (trial signup, subscription, upgrade). This guide covers each step with copy-paste examples, including a Next.js implementation.
What will you track?
| Event Type | Example | Purpose |
|---|---|---|
| Pageviews | Pricing, features, blog | Traffic analysis |
| Microconversions | Plan selection, form steps | Funnel optimization |
| Conversions | Trial signup, subscription | Revenue attribution |
Step 1: Basic Installation
Add the tracking script to your marketing site and app:
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ACCOUNT_ID" defer></script>
Content Grouping for SaaS
<!-- Marketing pages -->
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=marketing" defer></script>
<!-- Pricing page -->
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=pricing" defer></script>
<!-- Blog -->
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=blog" defer></script>
<!-- Documentation -->
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=docs" defer></script>
<!-- App (logged in) -->
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=app" defer></script>
<!-- Onboarding -->
<script src="https://t.sealmetrics.com/t.js?id=YOUR_ID&group=onboarding" defer></script>
Step 2: Track Pricing Page Interactions
Plan Selection
// Track when user clicks on a plan
document.querySelectorAll('.plan-card').forEach(function(card) {
card.addEventListener('click', function() {
sealmetrics.micro('select_plan', {
plan: this.dataset.plan, // 'starter', 'pro', 'enterprise'
billing: document.querySelector('.billing-toggle.active').dataset.billing // 'monthly', 'yearly'
});
});
});
Billing Toggle
// Track monthly/yearly toggle
document.querySelectorAll('.billing-toggle').forEach(function(toggle) {
toggle.addEventListener('click', function() {
sealmetrics.micro('toggle_billing', {
selected: this.dataset.billing // 'monthly' or 'yearly'
});
});
});
CTA Clicks
// Track "Start Trial" or "Get Started" clicks
document.querySelectorAll('.cta-start-trial').forEach(function(button) {
button.addEventListener('click', function() {
sealmetrics.micro('click_start_trial', {
plan: this.dataset.plan,
location: this.dataset.location // 'hero', 'pricing', 'footer'
});
});
});
Feature Comparison
// Track when user opens feature comparison
document.querySelector('.compare-plans').addEventListener('click', function() {
sealmetrics.micro('view_comparison');
});
Step 3: Track Signup Funnel
Multi-step Signup Form
// Step 1: Email entered
document.querySelector('#signup-email').addEventListener('blur', function() {
if (this.value && this.checkValidity()) {
sealmetrics.micro('signup_step_1', {
step: 'email_entered'
});
}
});
// Step 2: Password created
document.querySelector('#signup-password').addEventListener('blur', function() {
if (this.value) {
sealmetrics.micro('signup_step_2', {
step: 'password_created'
});
}
});
// Step 3: Company info
document.querySelector('#company-form').addEventListener('submit', function() {
sealmetrics.micro('signup_step_3', {
step: 'company_info',
company_size: document.querySelector('[name="company_size"]').value
});
});
// Final: Account created (CONVERSION)
// Track on the post-signup/welcome page
sealmetrics.conv('signup', 0, {
plan: 'trial',
source: document.referrer.includes('pricing') ? 'pricing' : 'direct'
});
Single-page Signup
document.querySelector('#signup-form').addEventListener('submit', function(e) {
// Track before form submits
sealmetrics.micro('signup_submitted', {
plan: document.querySelector('[name="plan"]').value
});
});
// On success callback or success page
function onSignupSuccess(user) {
sealmetrics.conv('signup', 0, {
plan: user.plan,
trial_days: '14'
});
}
Step 4: Track Onboarding
Track how users progress through onboarding to identify drop-off points.
Onboarding Checklist
// Generic onboarding step tracker
function trackOnboardingStep(stepName, stepNumber, data) {
sealmetrics.micro('onboarding_' + stepName, {
step_number: stepNumber.toString(),
...data
});
}
// Step 1: Profile completed
trackOnboardingStep('profile_completed', 1, {
has_avatar: document.querySelector('#avatar').src ? 'yes' : 'no'
});
// Step 2: First project created
trackOnboardingStep('project_created', 2, {
project_type: projectType
});
// Step 3: Team member invited
trackOnboardingStep('team_invited', 3, {
invites_sent: inviteCount.toString()
});
// Step 4: Integration connected
trackOnboardingStep('integration_connected', 4, {
integration: integrationName // 'slack', 'github', 'jira'
});
// Step 5: First action completed
trackOnboardingStep('first_action', 5, {
action_type: actionType
});
Onboarding Completed
// When user completes all onboarding steps
sealmetrics.micro('onboarding_completed', {
time_to_complete: calculateDays(signupDate, new Date()),
steps_completed: '5'
});
Skip Onboarding
document.querySelector('.skip-onboarding').addEventListener('click', function() {
sealmetrics.micro('onboarding_skipped', {
last_step: currentStep.toString()
});
});
Step 5: Track Feature Usage
Track which features users engage with to understand product-market fit.
Feature Activation
// First time using a feature
function trackFeatureActivation(featureName) {
if (!localStorage.getItem('activated_' + featureName)) {
sealmetrics.micro('feature_activated', {
feature: featureName
});
localStorage.setItem('activated_' + featureName, 'true');
}
}
// Examples
trackFeatureActivation('dashboard');
trackFeatureActivation('reports');
trackFeatureActivation('exports');
trackFeatureActivation('api');
trackFeatureActivation('integrations');
Key Actions
// Track important user actions
sealmetrics.micro('create_report', {
report_type: reportType
});
sealmetrics.micro('export_data', {
format: 'csv',
rows: rowCount.toString()
});
sealmetrics.micro('invite_team_member', {
role: memberRole
});
sealmetrics.micro('connect_integration', {
integration: integrationName
});
Step 6: Track Subscription Conversions
Trial to Paid
// When user enters payment info and subscribes
sealmetrics.conv('subscription', monthlyPrice, {
plan: 'pro',
billing_cycle: 'monthly',
currency: 'USD',
trial_days_used: trialDaysUsed.toString()
});
Plan Upgrade
// When user upgrades to a higher plan
sealmetrics.conv('upgrade', priceDifference, {
from_plan: 'starter',
to_plan: 'pro',
billing_cycle: 'monthly',
currency: 'USD'
});
Plan Downgrade
// Track downgrades for churn analysis
sealmetrics.micro('downgrade', {
from_plan: 'pro',
to_plan: 'starter',
reason: selectedReason // from exit survey
});
Annual Upgrade
// When user switches from monthly to annual
sealmetrics.conv('annual_upgrade', annualPrice, {
plan: 'pro',
previous_billing: 'monthly',
savings: savingsAmount.toString(),
currency: 'USD'
});
Step 7: Track Churn Signals
Cancel Flow
// User clicks cancel
sealmetrics.micro('cancel_initiated');
// User selects reason
sealmetrics.micro('cancel_reason', {
reason: selectedReason // 'too_expensive', 'not_using', 'missing_feature', etc.
});
// Offer accepted (save)
sealmetrics.micro('cancel_saved', {
offer: acceptedOffer // 'discount', 'pause', 'downgrade'
});
// Final cancellation
sealmetrics.micro('cancel_confirmed', {
reason: finalReason,
days_as_customer: customerDays.toString(),
plan: currentPlan
});
Reactivation
// When a churned user returns and subscribes again
sealmetrics.conv('reactivation', monthlyPrice, {
plan: 'pro',
days_churned: daysSinceCancellation.toString(),
previous_plan: previousPlan
});
Complete SaaS Funnel
┌─────────────────────────────────────────────────────────────────┐
│ SaaS FUNNEL │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ACQUISITION │
│ ─────────── │
│ Landing ──► Pricing ──► Select Plan ──► Start Trial │
│ (pv) (pv) (micro) (micro) │
│ │
│ ACTIVATION │
│ ────────── │
│ Signup ──► Onboarding Steps ──► Feature Activation │
│ (CONV) (micro x N) (micro) │
│ │
│ REVENUE │
│ ─────── │
│ Trial End ──► Enter Payment ──► Subscribe │
│ (micro) (CONV) │
│ │
│ EXPANSION │
│ ───────── │
│ Feature Usage ──► Upgrade ──► Annual │
│ (micro) (CONV) (CONV) │
│ │
└─────────────────────────────────────────────────────────────────┘
Example: Complete Implementation
Marketing Site (Next.js)
// components/PricingCard.tsx
export function PricingCard({ plan, price, billing }) {
const handleSelect = () => {
if (typeof sealmetrics !== 'undefined') {
sealmetrics.micro('select_plan', {
plan: plan,
billing: billing,
price: price.toString()
});
}
router.push(`/signup?plan=${plan}&billing=${billing}`);
};
return (
<div className="plan-card" onClick={handleSelect}>
{/* Plan details */}
</div>
);
}
Signup Page
// pages/signup.tsx
export default function Signup() {
const searchParams = useSearchParams();
const plan = searchParams.get('plan') || 'starter';
const handleSubmit = async (formData) => {
try {
const user = await createAccount(formData);
// Track signup conversion
if (typeof sealmetrics !== 'undefined') {
sealmetrics.conv('signup', 0, {
plan: plan,
source: document.referrer.includes('pricing') ? 'pricing' : 'other'
});
}
router.push('/onboarding');
} catch (error) {
// Handle error
}
};
return (
<form onSubmit={handleSubmit}>
{/* Form fields */}
</form>
);
}
App Dashboard
// components/UpgradeButton.tsx
export function UpgradeButton({ toPlan, price }) {
const handleUpgrade = async () => {
const result = await processUpgrade(toPlan);
if (result.success && typeof sealmetrics !== 'undefined') {
sealmetrics.conv('upgrade', price, {
from_plan: currentPlan,
to_plan: toPlan,
billing_cycle: billingCycle,
currency: 'USD'
});
}
};
return (
<button onClick={handleUpgrade}>
Upgrade to {toPlan}
</button>
);
}
Which SaaS metrics should you track?
| Metric | How to Calculate | Events Needed |
|---|---|---|
| Visitor → Trial | signup / entrances | pageview, signup |
| Trial → Paid | subscription / signup | signup, subscription |
| Onboarding Completion | onboarding_completed / signup | signup, onboarding_* |
| Feature Adoption | feature_activated / active users | feature_activated |
| Expansion Revenue | upgrade + annual_upgrade value | upgrade, annual_upgrade |
| Churn Rate | cancel_confirmed / active subscriptions | cancel_confirmed |
Dashboard Analysis
After implementing, analyze:
Acquisition
- Which channels drive trial signups
- Pricing page conversion rate
- Plan preference by source
Activation
- Onboarding completion rate
- Time to first value
- Feature activation patterns
Revenue
- Trial to paid conversion by plan
- MRR by acquisition source
- Upgrade patterns
Retention
- Churn reasons
- Feature usage before churn
- Reactivation success
In short
- Conversions:
signup(trial, amount 0),subscription,upgrade,annual_upgradeandreactivationwith the plan price; everything in between (plan selection, onboarding steps, feature activation, cancel flow) is a microconversion. - Key ratios: Visitor → Trial (signup / entrances), Trial → Paid (subscription / signup), onboarding completion and churn (cancel_confirmed / active subscriptions).
- Use content groups (marketing, pricing, blog, docs, app, onboarding) so acquisition and activation can be analyzed separately.
Related documentation
- Understanding Event Properties in Sealmetrics — enrich signup, onboarding, and upgrade events with custom properties
- Installation — add the tracking script to your marketing site and app
- Funnel Report — visualize the trial-to-paid and onboarding funnels
- Conversions Report — analyze subscriptions, upgrades, and MRR by channel
- Lead Generation — a sibling guide for tracking demo requests and B2B forms
Was this page helpful?