Privacy 7 min read

Form Analytics Without User Tracking: It's Possible

Learn how to measure form performance, conversion rates, and user behavior without invasive tracking or compromising privacy.

By VeilForms Team

“We need analytics” often becomes an excuse for invasive user tracking. But you can measure what matters without knowing who your users are.

The Problem with Traditional Form Analytics

Most form analytics tools track:

  • Individual user identities
  • Browsing history across sites
  • Device fingerprints
  • IP addresses and locations
  • Session recordings
  • Mouse movements and clicks

This data is then:

  • Stored indefinitely
  • Shared with third parties
  • Used for ad targeting
  • Vulnerable to breaches

All to answer questions like “how many people completed my form?”

There’s a better way.

What You Actually Need to Know

Be honest: what decisions do your form analytics inform?

  1. Is my form working? (completion rate)
  2. Where do people abandon? (drop-off points)
  3. Are there errors? (error rates by field)
  4. Is performance acceptable? (load times, submission times)
  5. How are submissions trending? (volume over time)

None of these require knowing who specific users are.

Privacy-First Analytics Approach

Aggregate, Don’t Track

Instead of: “User #12345 abandoned at email field” Use: “15% of users abandon at email field”

The insight is the same. The privacy impact is vastly different.

Event-Based, Not User-Based

Track events, not people:

// Bad: User-based tracking
analytics.identify('user_123');
analytics.track('form_started', { userId: 'user_123' });

// Good: Event-based tracking
analytics.increment('form_started_count');
analytics.recordTiming('form_load_time', 234);

Session Isolation

If you need session-level data, use ephemeral session IDs:

// Generate session ID that expires with the tab
const sessionId = crypto.randomUUID();
// No cookies, no persistence, no cross-site tracking

Metrics You Can Measure Privately

Form Views

Count page views without identifying viewers:

// Increment counter, nothing more
await fetch('/api/analytics', {
  method: 'POST',
  body: JSON.stringify({
    event: 'form_view',
    formId: 'contact'
  })
});

Completion Rate

Completion Rate = Submissions / Views × 100

Track both as counters, calculate the ratio.

Field-Level Drop-off

Track which field was last interacted with before abandonment:

let lastField = null;

form.querySelectorAll('input, textarea, select').forEach(field => {
  field.addEventListener('focus', () => {
    lastField = field.name;
  });
});

window.addEventListener('beforeunload', () => {
  if (lastField && !formSubmitted) {
    navigator.sendBeacon('/api/analytics', JSON.stringify({
      event: 'form_abandon',
      formId: 'contact',
      lastField: lastField
    }));
  }
});

Result: “30% of abandonments happen after the phone field” without knowing who.

Error Rates

Track validation errors by field:

function trackError(fieldName, errorType) {
  fetch('/api/analytics', {
    method: 'POST',
    body: JSON.stringify({
      event: 'validation_error',
      formId: 'contact',
      field: fieldName,
      errorType: errorType // e.g., 'required', 'format', 'length'
    })
  });
}

Result: “Email format errors occur on 12% of submissions”

Time to Complete

Measure how long forms take:

const startTime = Date.now();

form.addEventListener('submit', () => {
  const duration = Date.now() - startTime;
  navigator.sendBeacon('/api/analytics', JSON.stringify({
    event: 'form_complete',
    formId: 'contact',
    durationMs: duration
  }));
});

Result: “Median completion time is 45 seconds”

Submission Volume

Track submissions over time:

// Server-side: increment daily counter
await redis.incr(`submissions:contact:${today}`);

Result: Time-series data showing trends without user details.

VeilForms Analytics

VeilForms includes privacy-first analytics:

What We Track

  • Form views (count only)
  • Submissions (count only)
  • Error rates (aggregate)
  • Performance metrics (aggregate)

What We Don’t Track

  • User identities
  • IP addresses
  • Device fingerprints
  • Cross-site behavior
  • Individual session recordings

Dashboard Metrics

Contact Form (Last 30 Days)
├── Views: 1,234
├── Submissions: 456
├── Completion Rate: 37%
├── Avg. Time to Complete: 42s
└── Error Rate: 8%

Field Performance
├── Name: 2% errors
├── Email: 12% errors (format)
├── Phone: 15% drop-off
└── Message: 1% errors

All aggregate. No individual user data.

Implementing Your Own Privacy Analytics

If you’re building custom analytics, follow these principles:

1. Minimize Collection

Only collect what you’ll actually use. “Nice to have” data becomes a liability.

2. Aggregate Early

Don’t store individual events if you only need totals:

// Instead of storing every event
INSERT INTO events (formId, field, timestamp) VALUES (...)

// Store aggregates directly
UPDATE form_stats SET view_count = view_count + 1 WHERE form_id = ?

3. Set Retention Limits

// Delete detailed data after 30 days
DELETE FROM form_analytics WHERE created_at < NOW() - INTERVAL 30 DAY;
// Keep only aggregates long-term

4. No Third-Party Scripts

Every analytics script you add can track your users. Self-host or use privacy-focused alternatives.

5. Document What You Collect

Be transparent. If you collect it, disclose it in your privacy policy.

Tools for Privacy-First Analytics

Self-Hosted Options

  • Plausible - Privacy-focused, GDPR compliant
  • Umami - Simple, fast, no cookies
  • Fathom - Privacy-first with EU hosting

Custom Implementation

Build exactly what you need:

// Minimal analytics endpoint
app.post('/api/analytics', (req, res) => {
  const { event, formId } = req.body;

  // Store only aggregates
  switch (event) {
    case 'form_view':
      incrementCounter(`views:${formId}`);
      break;
    case 'form_submit':
      incrementCounter(`submissions:${formId}`);
      break;
    case 'form_error':
      incrementCounter(`errors:${formId}:${req.body.field}`);
      break;
  }

  res.status(204).end();
});

The Bottom Line

You don’t need to spy on users to understand your forms. Aggregate metrics tell you what’s working and what isn’t—without the privacy cost.

Questions to ask any analytics tool:

  1. Can I get the same insights with less data?
  2. Do I need user-level detail, or are aggregates sufficient?
  3. What happens to this data long-term?
  4. Who else has access to it?

Choose tools that respect your users. They’ll thank you for it (statistically speaking).


Want form analytics without the tracking? VeilForms includes privacy-first metrics out of the box.