Skip to main content

Sending custom events

Even though the Analytics module supports GA's Enhanced Ecommerce by default, a store may occasionally need to monitor customer activity not covered by the Analytics module. In these cases, it is still possible to use the sendAnalyticsEvent and useAnalyticsEvent utils to fire and intercept custom events.


We strongly recommend using the Analytics module to send custom events. This will help you centralize all tracking-related events in a single tool and, consequently, write more consistent, readable, and maintainable code.

In the following step by step, you'll learn how to define and send custom events.

Step by step

Step 1 - Declaring an interface for your custom event

To fire a custom event, you first need to declare an interface that describes the structure of your event object, including all its properties and types. To do that, you can

Creating a new event interface

You can use the sendAnalyticsEvent function to create a custom event interface. This function demands that the event contains two properties:

  • name (string)- name of the event presented in Analytics reports. The name doesn't need to follow any event name conventions related to natively supported events.
  • params (any) - Any type and value used by your custom event.

Take the following example of an arbitrary event:

import { sendAnalyticsEvent } from '@faststore/sdk'

interface ArbitraryEvent {
name: 'arbitrary-event',
params: string
foo: number
bar: boolean

/* ... */

sendAnalyticsEvent<ArbitraryEvent>({ name, params, foo, bar })

Extending existing types from the Analytics module

If your event is related to an existing one, you can extended existing types from the Analytics module by using the generics available on the sendAnalyticsEvent function.

Take the following example where the AddToCartEvent interface is extended to also accept the foo property:

import type { AddToCartEvent } from '@faststore/sdk'
import { sendAnalyticsEvent } from '@faststore/sdk'

interface AddToCartExtended extends AddToCartEvent {
foo: string

/* ... */

sendAnalyticsEvent<AddToCartExtended>({ name, params, foo })

Overriding multiple types

If you have multiple types to override, you can do that all at once and re-export the sendAnalyticsEvent function with the desired types:

/* types.ts */
import { sendAnalyticsEvent } from '@faststore/sdk'

type AddToCartExtended = /* ... */
type RemoveFromCartExtended = /* ... */
type ViewItemExtended = /* ... */
type SelectItemExtended = /* ... */

type ExtendedEvents =
| AddToCartExtended
| RemoveFromCartExtended
| ViewItemExtended
| SelectItemExtended

type SendExtendedAnalyticsEvent = (event: ExtendedEvents) => void

export const sendExtendedAnalyticsEvent: SendExtendedAnalyticsEvent = (event) =>
/* MyComponent.tsx */
import { sendExtendedAnalyticsEvent } from './types'

/* ... */

sendExtendedAnalyticsEvent({ /* Extended event object */})

Step 2 - Intercepting custom events

After creating or extending an event interface, you'll need to intercept these events using the useAnalyticsEvent hook. You can do that as in the following:

import { useAnalyticsEvent } from '@faststore/sdk'

import type { ArbitraryEvent } from './types'

export const AnalyticsHandler = () => {
useAnalyticsEvent((event: ArbitraryEvent) => {

/* ... */

return null

Also, notice that to target extended properties of events, you'll also need to configure the types of your useAnalyticsEvent callback function in order to expect an event of such type.

import { useAnalyticsEvent } from '@faststore/sdk'

import type { ExtendedEvents } from './types'

export const AnalyticsHandler = () => {
* By typing the callback function with the extended types, you are able to
* reference properties that are not natively offered by the analytics module.
useAnalyticsEvent((event: ExtendedEvents) => {
/* ... */

/* ... */

return null

Step 3 - Firing custom events

Now that you have declared your event interface and intercepted them with the useAnalyticsEvent hook, you can implement it in your components to fire the event when desired.

import { useCallback } from 'react'
import { sendAnalyticsEvent } from '@faststore/sdk'

const MyComponent = () => {
const arbitraryEvent = useCallback(() => {
/* ... */

const arbitraryEvent = {
type: 'arbitrary-event',
data: {
items: [
/* ... */

}, [])

return <button onClick={arbitraryEvent}>Arbitrary button</button>

Didn't find your answers? Ask the Community. For documentation suggestions, submit your feedback.