Documentation / Custom Events

Custom Events

Track button clicks, form submissions, purchases, and any interaction that matters to your business. Events are collected without cookies and without storing any personal data.

Privacy-first by design

Custom events are linked to an anonymous visitor hash, never to an IP address, email, or any personal identifier. No cookies are set. GPC and DNT signals are honoured, and visitors can explicitly opt out via ghostlyx('opt-out') in all these cases events are silently dropped server-side as well as client-side. Properties you attach to events are stored as-is, so avoid including personal data in event names or props.

Quick start

Make sure the GhostlyX tracking snippet is loaded on the page, then call window.ghostlyx() with an event name. That's it.

JavaScript
// Fire a named event
ghostlyx('Signup');

// Fire an event with optional metadata
ghostlyx('Purchase', {
  plan:    'pro',
  revenue: 29,
});

Events appear in the Custom Events panel on your site's analytics page within seconds.

Sending events

Call ghostlyx(name) anywhere in your JavaScript inside click handlers, form submit listeners, or after async operations complete.

JS Button click

Attach a listener directly on the element or delegate from a parent.

document.getElementById('upgrade-btn').addEventListener('click', () => {
  ghostlyx('Clicked Upgrade');
});
JS Form submission

Fire the event before submitting so it is captured even if the page navigates away immediately. The event is sent via navigator.sendBeacon which survives navigation.

document.getElementById('contact-form').addEventListener('submit', (e) => {
  ghostlyx('Contact Form Submitted');
  // form will continue to submit normally
});
JS Event with properties

Attach a flat object of metadata as the second argument. Properties must be strings, numbers, or booleans. Do not include personal data such as names, email addresses, or user IDs.

ghostlyx('Purchase', {
  plan:     'growth',
  revenue:  79,
  currency: 'USD',
  trial:    false,
});

Zero-code auto-tracking

Enable these optional behaviours with data-* attributes on the script tag. No JavaScript required.

data-outbound-links="true" Outbound link clicks

Fires an Outbound Link: Click event when a visitor clicks a link to a different hostname. The target URL is included as a property.

<script src="https://ghostlyx.com/js/script.min.js"
  data-site-id="YOUR_SITE_ID"
  data-outbound-links="true"
  defer></script>
data-file-downloads="true" File download clicks

Fires a File Download event when a visitor clicks a link to a downloadable file (pdf, zip, xlsx, docx, mp4, and more). The filename is included as a property.

<script src="https://ghostlyx.com/js/script.min.js"
  data-site-id="YOUR_SITE_ID"
  data-file-downloads="true"
  defer></script>
data-form-submissions="true" Form submit events

Fires a Form Submission event on every form submit. The form is identified by its id, name, or action attribute (whichever is present first). No form field values are ever captured.

<script src="https://ghostlyx.com/js/script.min.js"
  data-site-id="YOUR_SITE_ID"
  data-form-submissions="true"
  defer></script>

Privacy behaviour

Custom events follow the same privacy rules as pageview tracking. The script silently drops any event and exposes a no-op window.ghostlyx() when any of these conditions are true:

Global Privacy Control navigator.globalPrivacyControl === true The visitor's browser or extension has set the GPC signal. Events are never sent.
Do Not Track navigator.doNotTrack === "1" The visitor has enabled the legacy Do Not Track preference. Events are never sent.
Explicit opt-out ghostlyx('opt-out') The visitor called the opt-out API. The flag is stored in localStorage and persists across sessions.

What is stored

Event name The name you pass to ghostlyx(), e.g. "Signup".
Page path The URL path where the event fired (no query string or hash by default).
Properties The optional flat object you supply. Avoid personal data here.
Visitor hash A SHA-256 hash of IP + user-agent + site ID + calendar day. It resets every day and cannot be reversed to an IP address.
Browser / OS / Device Parsed from the user-agent header. The raw user-agent string is never stored.
Country Resolved via IP geolocation using a local MaxMind database. The IP is never written to the database. It is used only within the request to derive the anonymous visitor hash and resolve the country, then discarded. City and region are not stored for events.

Best practices

Use descriptive, human-readable names

Prefer "Clicked Upgrade" over "btn_click_1". Names appear as-is in your dashboard so they should be meaningful to your whole team.

Keep event names consistent

Changing the name of an event creates a new entry in your dashboard. Decide on naming conventions early and stick to them.

Never include personal data in event names or props

Do not pass email addresses, names, IP addresses, or any identifier that could be linked back to a real person. This keeps you GDPR and CCPA compliant without any extra work.

Prefer flat props objects

Nested objects are not supported. Keep values to strings, numbers, and booleans.

Use goals to track conversions

If you want conversion rates, create a Goal in your dashboard that targets the event name. Goals add completion counts, unique converter counts, and a conversion rate alongside your event data.

Ready to start tracking events?