Skip to content

Commit

Permalink
docs(sdk): improve analytics sdk documentation (#1393)
Browse files Browse the repository at this point in the history
* docs(sdk): improve analytics sdk documentation

* docs: configure sidebar for new analytics sdk docs

* chore: test converting analytics files to mdx

* Update Analytics.md

* chore: convert files back to .md

Co-authored-by: Carolina Menezes <60782333+carolinamenezes@users.noreply.github.com>
  • Loading branch information
icazevedo and carolinamenezes authored Jul 4, 2022
1 parent b146fa2 commit 8eb2124
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 99 deletions.
107 changes: 10 additions & 97 deletions apps/docs/docs/reference/sdk/Analytics.md
Original file line number Diff line number Diff line change
@@ -1,104 +1,17 @@
# Analytics
---
id: analytics
---

The analytics module lets you manage analytics events based on [Google Analytics 4 (GA4) data model](https://developers.google.com/analytics/devguides/collection/ga4/reference/events). The events are wrapped and then sent over standard `postMessage` calls, which share the event only with the website's origin. The events are received via event listeners. It also supports sending and receiving custom events as the types on the helper functions can be overridden.
# Analytics module

### Sending events
The analytics module lets you manage events in a simple way. You send an event using this module, the event is wrapped and then sent to the window over standard `postMessage` calls, which share the event only with the website's origin. This module provides a React Hook so it's possible to intercept the fired events. can be received via event listeners.

Analytics events can be sent by using the `sendAnalyticsEvent` function and it's especially useful to send common ecommerce events such as `add_to_cart`. It enforces standard GA4 events via type check and IntelliSense suggestions, but this behavior can be altered via overriding the function's types.
It's important to note that events sent using the analytics module are not directly sent to any analytics provider such as Google Analytics. This has to be done manually by using the provided hook.

To fire a standard GA4 event:
The analytics module supports sending and receiving events of any shape, so you can implement your own types and override default ones.

```tsx
import { useCallback } from 'react'
import { sendAnalyticsEvent } from '@faststore/sdk'
# Google Analytics support

const MyComponent = () => {
const addToCartCallback = useCallback(() => {
/* ... */
Google Analytics is by far the industry leading analytics solution that most ecommerce websites use, and the analytics module was built with it in mind. All helper functions and hooks use the [Google Analytics 4 (GA4) data model](https://developers.google.com/analytics/devguides/collection/ga4/reference/events) by default, which means GA4 events will be suggested along with recommended properties and [IntelliSense](https://docs.microsoft.com/pt-br/visualstudio/ide/using-intellisense) support.

const addToCartEvent = {
type: 'add_to_cart',
data: {
items: [
/* ... */
],
},
}

sendAnalyticsEvent(addToCartEvent)
}, [])

return <button onClick={addToCartCallback}>Add to cart</button>
}
```

For custom events, define the type of the event and override the default type via `sendAnalyticsEvent` generics. Your custom event has to have a type and a data field of any kind.

To fire a custom event:

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

interface CustomEvent {
type: 'custom_event'
data: {
customProperty?: string
}
}

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

const customEvent = {
type: 'custom_event',
data: {
customProperty: 'value',
},
}

sendAnalyticsEvent<CustomEvent>(customEvent)
}, [])

return <button onClick={customEventCallback}>Press here</button>
}
```

### Receiving events

It's possible to receive analytics events by using the `useAnalyticsEvent` hook. It accepts a handler that will be called every time an event sent by `sendAnalyticsEvent` arrives. For that reason, it can fire both for standard GA4 events and for custom events that a library or a component might be sending. To help users be aware of that possibility, the event received by the handler is, by default, typed as `UnknownEvent`. You can assume it has another type by simply typing the callback function as you wish, but be careful with the unexpected events that might come to this handler.

To use the `useAnalyticsEvent` hook:

```tsx
import { useAnalyticsEvent } from '@faststore/sdk'
import type { AnalyticsEvent } from '@faststore/sdk'

/**
* Notice that we typed it as AnalyticsEvent, but there may be events that are not from this type.
*
* Since we're dealing with it on a switch and we are providing an empty default clause,
* we're not gonna have issues receiving custom events sent by other components or libraries.
*/
function handler(event: AnalyticsEvent) {
switch (event.type) {
case 'add_to_cart': {
/* ... */
}

/* ... */

default: {
/* ... */
}
}
}

// In your component:
const MyComponent = () => {
useAnalyticsEvent(handler)

/* ... */
}
```
To send the events to Google Analytics, you should listen to when they're sent - by using the [useAnalyticsEvent](/reference/sdk/analytics/useAnalyticsEvent) hook - and add them to the `dataLayer` in case you're using Google Tag Manager (recommended) or call the `gtag` function directly if you're using gtag's script directly. The analytics module doesn't do this automatically, so it has to be executed on the store.
48 changes: 48 additions & 0 deletions apps/docs/docs/reference/sdk/analytics/how-to-extend-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# How to extend and customize native types

One of the major features the analytics module offers are its types. They're all based on [Google Analytics 4 (GA4) data model](https://developers.google.com/analytics/devguides/collection/ga4/reference/events), and they're especially focused on the [Enhanced Ecommerce](https://support.google.com/tagmanager/answer/6107169) capabilities.

Although the recommended parameters by each analytics providers are often the most important ones, it's quite common to send additional properties to them in order to monitor specific behaviors that are uniquely valuable to a store or a store sectors.

The analytics module supports this behavior natively and offers ways to make it easy to incorporate it without losing code safety features. It does that by accepting custom types and exporting its own types so that users don't have the need to rewrite all of them to add minor additions. Also, these types are built with generics, which means you can rewrite only a small part of them if you really need to.

## Available types

The types for all events are available for use and extension. Here's the list of the events the analytics module natively supports: `add_payment_info`, `purchase`, `signup`, `add_shipping_info`, `refund`, `add_to_cart`, `remove_from_cart`, `view_cart`, `add_to_wishlist`, `search`, `view_item`, `begin_checkout`, `select_item`, `view_item_list`, `select_promotion`, `view_promotion`, `login`, `share`. For each of these events, at least two types are exported: one being the type of the event params and the other being the event type itself.

As an example, the `add_to_cart` has two exported types: `AddToCartParams<T extends Item = Item>` and `AddToCartEvent<T extends Item = Item>`.

Also, there are types there are common to all events, such as the `Item` type. These types are particulary useful when overriding `Item` properties or a whole `Item` itself (usually via generics).

## Extending types

You can extend the available types by using common TS techniques such as [Type Aliases or Extended Interfaces](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#differences-between-type-aliases-and-interfaces).

```ts
import type { AddToCartEvent } from '@faststore/sdk'

/**
* AddToCartExtended will have all the AddToCartEvent properties (name, params) plus the new properties (foo)
*/
interface AddToCartExtended extends AddToCartEvent {
foo: string
}
```

Also, when available, you can use [generics](https://www.typescriptlang.org/docs/handbook/2/generics.html) to override the Item property in events.


```ts
import type { AddToCartEvent, Item } from '@faststore/sdk'

interface ItemExtension {
dimension10: string
}

type ItemExtended = Item & ItemExtension

/**
* AddToCartExtended will have the same properties as AddToCartEvent (name, params), but the items inside the params property will now have the ItemExtended type.
*/
type AddToCartWithExtendedItems = AddToCartEvent<ItemExtended>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# How to send custom events

Sometimes a store needs to track user behavior that's not covered by [GA's Enhanced Ecommerce](https://support.google.com/tagmanager/answer/6107169), which is natively supported by the analytics module. In those cases, you can still use the same functions and hooks to fire and intercept custom events. This way, you centralize all tracking-related events in a single tool, which helps you write code that's more consistant, readable, and maintainable.

## sendAnalyticsEvent
You can use [extended types](/reference/sdk/analytics/how-to-extend-types) for sending custom events. You'll need to use the generics available on the [sendAnalyticsEvent](/reference/sdk/analytics/sendAnalyticsEvent) function.

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

interface AddToCartExtended extends AddToCartEvent {
foo: string
}

/* ... */

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

### Send arbitrary event
The `sendAnalyticsEvent` function demands that the event object contains two properties: `name` and `type`. These two properties can be of any type and value, and don't have to follow any event name conventions related to the natively supported events.

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

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

/* ... */

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

### Override 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:

```ts
/* 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) =>
sendAnalyticsEvent<ExtendedEvents>(event)
```

```ts
/* MyComponent.tsx */
import { sendExtendedAnalyticsEvent } from './types'

/* ... */

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

## useAnalyticsEvent

To target extended properties of events when intercepting them, you can configure the types of your [useAnalyticsEvent](/reference/sdk/analytics/useAnalyticsEvent) callback function to expect an event of such type.

```ts
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
}
```
57 changes: 57 additions & 0 deletions apps/docs/docs/reference/sdk/analytics/sendAnalyticsEvent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# sendAnalyticsEvent

The analytics module provides the `sendAnalyticsEvent` function as the way to fire events in the browser. These events are often related to ecommerce tracking capabilities. By default, the `sendAnalyticsEvent` suggests (via IntelliSense) and inforces (via TypeScript) [Google Analytics 4 (GA4) data model](https://developers.google.com/analytics/devguides/collection/ga4/reference/events).

`sendAnalyticsEvent` does not send events to any analytics provider. It is merely a way to centralize and aggregate tracking events. To intercept events fired with this function, use the hook [useAnalyticsEvent](/reference/sdk/analytics/useAnalyticsEvent). This function also supports [sending custom events](/reference/sdk/analytics/how-to-send-custom-events).

## How to use

To fire a supported GA4 event:

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

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

const addToCartEvent = {
type: 'add_to_cart',
data: {
items: [
/* ... */
],
},
}

sendAnalyticsEvent(addToCartEvent)
}, [])

return <button onClick={addToCartCallback}>Add to cart</button>
}
```

## Generics

The `sendAnalyticsEvent` function was built using [generics](https://www.typescriptlang.org/docs/handbook/2/generics.html), which means you can extend default types and override the default ones, obtaining the same suggestions and enforcements as you would with a natively supported event.

To provide a custom type referecence for `sendAnalyticsEvent`, do the following

```tsx
import { sendAnalyticsEvent } from '@faststore/sdk'

interface CustomEvent {
name: 'custom_event'
params: {
customProperty?: string
}
}

/**
* We're passing the CustomEvent to sendAnalyticsEvent. As you type, you'll receive code suggestions for all the properties of this type, including params subfields.
*/
sendAnalyticsEvent<CustomEvent>(/* ... */)
```

This is most commonly used to fire custom events or native events with custom properties in it. For more details, read the [How to extend and customize native types](/reference/sdk/analytics/how-to-extend-types) and [How to send custom events](/reference/sdk/analytics/how-to-send-custom-events) docs.
30 changes: 30 additions & 0 deletions apps/docs/docs/reference/sdk/analytics/useAnalyticsEvent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# useAnalyticsEvent

To intercept events that were fired using the analytics module, you should use the `useAnalyticsEvent` hook. It automatically detects which events were sent using the [sendAnalyticsEvent](/reference/sdk/analytics/sendAnalyticsEvent) function and provides a way to react to those events. The `useAnalyticsEvent` hook can be used to intercept both native and custom events.

## How to use
The `useAnalyticsEvent` hook accepts a callback function that runs whenever an event is fired.

The callback function you provide receives the event that triggered its execution as an argument. Ideally, this is the place you actually send the event to the analytics provider of you choice.

```tsx
import type { AnalyticsEvent } from '@faststore/sdk'
import { useAnalyticsEvent } from '@faststore

export const AnalyticsHandler = () => {
useAnalyticsEvent((event: AnalyticsEvent) => {
/**
* This is where you can send events to your analytics provider
*
* Example:
* window.dataLayer.push({ event: event.name, ecommerce: event.params })
*/
})

/* ... */
}
```

## External libraries

External libraries can also send events using the analytics module. This means that you might come across unexpected events being intercepted by `useAnalyticsEvent`. This is usually not a problem, since most common analytics providers don't break if you send additional (irrelevant) data to them. If you're using one that does, make sure to filter the events by name, so only the expected events are sent to the provider.
2 changes: 1 addition & 1 deletion apps/docs/docs/reference/sdk/faststore-sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ FastStore SDK is a simple, framework-agnostic implementation of Commerce APIs to

### Analytics

The analytics data layer is based on [the official GA4 specification](https://developers.google.com/gtagjs/reference/ga4-events).
The analytics module helps you create a simple and extensive event system to feed your data pool. It is biased towards Google Analytics 4, but supports any other analytics provider. Go to the [Analytics](/reference/sdk/analytics) page to learn more.

## Get started

Expand Down
13 changes: 12 additions & 1 deletion apps/docs/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,18 @@ module.exports = {
collapsed: true,
link: { type: 'doc', id: 'reference/sdk/faststore-sdk' },
items: [
'reference/sdk/Analytics',
{
type: 'category',
label: 'Analytics',
link: { type: 'doc', id: 'reference/sdk/analytics' },
collapsed: true,
items: [
{
type: 'autogenerated',
dirName: 'reference/sdk/analytics',
},
],
},
{
type: 'category',
label: 'Cart',
Expand Down

1 comment on commit 8eb2124

@vercel
Copy link

@vercel vercel bot commented on 8eb2124 Jul 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.