diff --git a/apps/docs/docs/reference/sdk/Analytics.md b/apps/docs/docs/reference/sdk/Analytics.md
index 70e9c50b9d..8059373033 100644
--- a/apps/docs/docs/reference/sdk/Analytics.md
+++ b/apps/docs/docs/reference/sdk/Analytics.md
@@ -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
-}
-```
-
-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)
- }, [])
-
- return
-}
-```
-
-### 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.
diff --git a/apps/docs/docs/reference/sdk/analytics/how-to-extend-types.md b/apps/docs/docs/reference/sdk/analytics/how-to-extend-types.md
new file mode 100644
index 0000000000..eee454dd00
--- /dev/null
+++ b/apps/docs/docs/reference/sdk/analytics/how-to-extend-types.md
@@ -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` and `AddToCartEvent`.
+
+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
+```
diff --git a/apps/docs/docs/reference/sdk/analytics/how-to-send-custom-events.md b/apps/docs/docs/reference/sdk/analytics/how-to-send-custom-events.md
new file mode 100644
index 0000000000..27f942f650
--- /dev/null
+++ b/apps/docs/docs/reference/sdk/analytics/how-to-send-custom-events.md
@@ -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({ 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({ 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(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
+}
+```
\ No newline at end of file
diff --git a/apps/docs/docs/reference/sdk/analytics/sendAnalyticsEvent.md b/apps/docs/docs/reference/sdk/analytics/sendAnalyticsEvent.md
new file mode 100644
index 0000000000..b2a5cade67
--- /dev/null
+++ b/apps/docs/docs/reference/sdk/analytics/sendAnalyticsEvent.md
@@ -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
+}
+```
+
+## 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(/* ... */)
+```
+
+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.
diff --git a/apps/docs/docs/reference/sdk/analytics/useAnalyticsEvent.md b/apps/docs/docs/reference/sdk/analytics/useAnalyticsEvent.md
new file mode 100644
index 0000000000..f252b68167
--- /dev/null
+++ b/apps/docs/docs/reference/sdk/analytics/useAnalyticsEvent.md
@@ -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.
\ No newline at end of file
diff --git a/apps/docs/docs/reference/sdk/faststore-sdk.md b/apps/docs/docs/reference/sdk/faststore-sdk.md
index 2fdbe34dba..a46018edc9 100644
--- a/apps/docs/docs/reference/sdk/faststore-sdk.md
+++ b/apps/docs/docs/reference/sdk/faststore-sdk.md
@@ -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
diff --git a/apps/docs/sidebars.js b/apps/docs/sidebars.js
index c91e8e201d..fbb951a524 100644
--- a/apps/docs/sidebars.js
+++ b/apps/docs/sidebars.js
@@ -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',