diff --git a/.vale.ini b/.vale.ini
new file mode 100644
index 0000000..58990c3
--- /dev/null
+++ b/.vale.ini
@@ -0,0 +1,8 @@
+StylesPath = styles
+Vocab = Formo
+MinAlertLevel = suggestion
+
+[*.{md,mdx}]
+BasedOnStyles = Vale
+
+TokenIgnores = \b(Wagmi|Solana|Onchain|Autocapture|Autocaptured|Serverless|formo)\b
diff --git a/data/concepts.mdx b/data/concepts.mdx
index d4829de..50fc704 100644
--- a/data/concepts.mdx
+++ b/data/concepts.mdx
@@ -36,7 +36,7 @@ Wallets are automatically linked to the user when multiple wallets are connected
### 3. Properties
Properties are **additional information about users and events.**
-- Event properties are attributes that describe details specific to the particular instance of an event. For example, if you had a Purchase Completed event, you could specify what the user purchased, the total value of the order, and the payment method used.
+- Event properties are attributes that describe details specific to the particular instance of an event. For example, if you had a Swap Completed event, you could specify the token pair, input amount, output amount, volume, and protocol fee.
- User properties are traits describing the user and apply across all their future events until the properties are modified. Formo's SDK captures several user properties by default, and you can also set up your own properties to track.
Properties examples:
@@ -44,4 +44,4 @@ Properties examples:
- A Page View event has page URL, referrer URL, and other metadata.
- A User has net worth and first-touch UTM parameter properties.
-When you track custom events, you can also set properties to describe the event. For example, if you had a Purchase Completed event, you could specify what the user purchased, the total value of the order, and the payment method used.
+When you track custom events, you can also set properties to describe the event. For example, if you had a Swap Completed event, you could specify the token pair, input amount, output amount, volume, and protocol fee.
diff --git a/data/events/track.mdx b/data/events/track.mdx
index b774b2d..43e9a32 100644
--- a/data/events/track.mdx
+++ b/data/events/track.mdx
@@ -6,17 +6,17 @@ description: 'Reference for the custom events used to record custom user actions
Record any [custom events](/features/product-analytics/custom-events) in your app,
along with properties that describe the action.
-Custom events can capture a broad range of actions, such as clicking a button or completing a purchase.
+Custom events can capture a broad range of actions, such as starting a swap or completing a deposit.
-Additional information about the event can be included in the properties field. For example, for a `Purchase Completed` event, you may want to include the product ids of the purchased products.
+Additional information about the event can be included in the properties field. For example, for a `Swap Completed` event, you may want to include the token pair, input amount, and output amount.
## Naming events
When naming events, Formo recommends establishing a consistent naming convention that uses:
- Consistent formatting: Event names are case sensitive.
-- A consistent syntax: Adopt nouns and past tense verbs like `Swap Reviewed` and `Order Submitted`. A standard of `[Noun] + [Past-Tense Verb]` ensures all your events are consistent.
-- A consistent actor: Does `Message Sent` mean that the user sent a message or that you sent a message to the user? If all your events are named in a way that reflects the user's perspective, the meaning is clear immediately.
+- A consistent syntax: Adopt nouns and past tense verbs like `Swap Completed` and `Deposit Submitted`. A standard of `[Noun] + [Past-Tense Verb]` ensures all your events are consistent.
+- A consistent actor: Does `Transaction Submitted` mean that the user submitted a transaction or that your app submitted it on their behalf? If all your events are named in a way that reflects the user's perspective, the meaning is clear immediately.
This allows everyone including you 6 months from now to instantly understand the meaning of an event.
@@ -29,9 +29,11 @@ Every custom event has `type` set to `track` and `event` set to your custom even
```json
{
"type": "track",
- "event": "Swap Reviewed",
+ "event": "Swap Completed",
"properties": {
- "rating": 5
+ "pair": "ETH/USDC",
+ "token_in": "ETH",
+ "token_out": "USDC"
}
}
```
@@ -56,20 +58,36 @@ Include these optional properties in a custom event to track values associated w
+For example, call `.track()` with the reserved properties alongside any other event properties:
+
+```typescript
+analytics.track('Swap Completed', {
+ pair: 'ETH/USDC',
+ token_in: 'ETH',
+ token_out: 'USDC',
+ amount_in: 1.5,
+ amount_out: 4500,
+ volume: 4500,
+ revenue: 13.5,
+ points: 50
+});
+```
+
## Sample Payload
```json
{
"type": "track",
- "event": "Product Reviewed",
+ "event": "Swap Completed",
"properties": {
- "volume": -100.5,
- "revenue": 20.5,
- "currency": "USD",
- "points": 100,
- "product_id" : "9578257311",
- "rating" : 3.0,
- "review_body" : "Good value for the price."
+ "pair": "ETH/USDC",
+ "token_in": "ETH",
+ "token_out": "USDC",
+ "amount_in": 1.5,
+ "amount_out": 4500,
+ "volume": 4500,
+ "revenue": 13.5,
+ "points": 50
}
}
-```
\ No newline at end of file
+```
diff --git a/data/metrics.mdx b/data/metrics.mdx
index fbf02cc..ff17170 100644
--- a/data/metrics.mdx
+++ b/data/metrics.mdx
@@ -35,7 +35,7 @@ How many times a page has been viewed across your site or app.
### Sessions
-A session (also known as a visit) is a set of actions that a user takes on your site.
+A session (also known as a visit) is a set of actions that a user takes on your site.
Formo counts unique session IDs. With the web SDK, each visitor's session is counted once per day, so one visitor can have multiple sessions across days.
### Session Duration
@@ -145,7 +145,7 @@ Users who visit your site or app for the first time within the selected time per
### Returning Users
-Users who have visited your site or app in previous time periods and return within the current period.
+Users who have visited your site or app in previous time periods and return within the current period.
### Resurrected Users
@@ -163,7 +163,7 @@ Users with no activity within the project's churn window.
Events are user-defined custom events. They have a name and optional metadata key/value pairs. When you expand the activity feed, you can view and filter the metadata.
-Metadata can be anything. For example, you can define an event Button clicked and track which button was clicked as the metadata field `button=Header`.
+Metadata can be anything. For example, you can define a `Swap Completed` event and track the swap pair as the metadata field `pair=ETH/USDC`.
### Top apps
diff --git a/features/product-analytics/custom-events.mdx b/features/product-analytics/custom-events.mdx
index a82588d..7ea24b8 100644
--- a/features/product-analytics/custom-events.mdx
+++ b/features/product-analytics/custom-events.mdx
@@ -1,6 +1,6 @@
---
title: 'Custom events'
-description: 'Define and track custom events like button clicks, form submissions, and purchases with structured properties using the Formo SDK Track API.'
+description: 'Define and track custom events like swaps, deposits, and quests with structured properties using the Formo SDK Track API.'
---
## Overview
@@ -22,8 +22,8 @@ Track actions that aren't captured automatically:
| Action | Why track it |
|--------|--------------|
-| Button clicks | Measure CTA effectiveness |
-| Form submissions | Track lead generation |
+| Swap submissions | Measure swap conversion |
+| Deposit completions | Track liquidity flows |
| Feature usage | Understand adoption |
| Errors | Debug user issues |
| Key conversions | Measure business outcomes |
@@ -47,7 +47,7 @@ Track actions that aren't captured automatically:
```javascript
// Track an event
- window.formo.track('Event Name', { property: 'value' });
+ window.formo.track('Swap Completed', { pair: 'ETH/USDC' });
```
@@ -73,9 +73,11 @@ analytics.track('Swap Completed', {
For events with monetary value, use special properties:
```typescript
-analytics.track('Trade Executed', {
+analytics.track('Swap Completed', {
pair: 'ETH/USDC',
- volume: 5000, // USD value of the trade
+ token_in: 'ETH',
+ token_out: 'USDC',
+ volume: 5000, // USD value of the swap
revenue: 25, // Revenue earned (e.g., fees)
points: 100 // Loyalty/reward points
});
@@ -167,21 +169,22 @@ analytics.track('Swap Failed', {
});
```
-### Example: Tracking feature adoption
+### Example: Tracking DeFi feature adoption
-Measure which features users engage with:
+Measure which protocol features users engage with:
```typescript
-// User opens a feature
-analytics.track('Feature Opened', {
- feature: 'Portfolio',
+// User opens a liquidity pool
+analytics.track('Pool Opened', {
+ pool_id: 'ETH/USDC',
source: 'sidebar'
});
-// User completes key action in feature
-analytics.track('Portfolio Export', {
- format: 'csv',
- date_range: '30d'
+// User completes a key action in the pool
+analytics.track('Liquidity Added', {
+ pool_id: 'ETH/USDC',
+ token_0: 'ETH',
+ token_1: 'USDC'
});
```
diff --git a/sdks/mobile.mdx b/sdks/mobile.mdx
index dc47e96..45fd670 100644
--- a/sdks/mobile.mdx
+++ b/sdks/mobile.mdx
@@ -230,14 +230,14 @@ formo.track('Swap Completed', {
});
// With reserved properties for analytics
-formo.track('Purchase Completed', {
- productId: 'premium-nft-001',
+formo.track('NFT Minted', {
+ collection: 'founders-pass',
+ tokenId: '001',
revenue: 99.99, // Reserved: revenue tracking
- currency: 'USD', // Reserved: currency for revenue
});
-formo.track('Achievement Unlocked', {
- achievementId: 'first_transaction',
+formo.track('Quest Completed', {
+ questId: 'first_swap',
points: 500, // Reserved: points tracking
});
diff --git a/sdks/server.mdx b/sdks/server.mdx
index 7f2a289..27320d1 100644
--- a/sdks/server.mdx
+++ b/sdks/server.mdx
@@ -53,11 +53,15 @@ To track custom events (actions, conversions, or backend states) use the [`track
await analytics.track({
address: "0x9798d87366bdfc5d70b300abdffc4f9e95369b3d", // optional: wallet address
anonymousId: uuid(), // optional: auto-generated if not provided
- event: "Purchase Completed", // required: event name
+ event: "Swap Completed", // required: event name
properties: {
- order_id: "123",
- revenue: 99.99,
- currency: "USD",
+ pair: "ETH/USDC",
+ token_in: "ETH",
+ token_out: "USDC",
+ amount_in: 1.5,
+ amount_out: 4500,
+ volume: 4500,
+ revenue: 13.5,
},
});
```
diff --git a/sdks/web.mdx b/sdks/web.mdx
index d1250ef..23d41ec 100644
--- a/sdks/web.mdx
+++ b/sdks/web.mdx
@@ -326,7 +326,7 @@ If no parameters are specified, the Formo SDK will attempt to auto-identify the
> The Web SDK automatically captures common events such as page views and wallet events (connect, disconnect, signature, transaction, etc) with full attribution (referrer, UTM, referrals.) You do not need to manually track them.
-To track custom events (in-app user actions, key conversions) use the [`track`](/data/events/track) function with details of what happenned:
+To track custom events (in-app user actions, key conversions) use the [`track`](/data/events/track) function with details of what happened:
```ts
import { useFormo } from '@formo/analytics';
@@ -826,7 +826,7 @@ npm install @formo/analytics @solana/client @solana/react-hooks
const formo = useFormo();
const handleClick = () => {
- formo.track('button_click', { page: 'home' });
+ formo.track('Swap Started', { pair: 'ETH/USDC' });
};
}
```
@@ -894,7 +894,7 @@ For Solana-only apps, set `evm: false` to disable EVM provider detection (EIP-11
The [Wagmi integration](#wagmi) automatically tracks wallet connects, disconnects, chain switches, transactions, and signatures by hooking into Wagmi's wallet adapter. The standard [React integration](#react--nextjs-without-wagmi) tracks wallet events by wrapping the EIP-1193 wallet provider to track signatures and transactions. Use the Wagmi integration if your dApp uses Wagmi and its hooks.
- Use [formo.track()](/data/events/track) to send custom events with any properties you need. For example: `formo.track('swap', { tokenIn: 'USDC', tokenOut: 'ETH', amount: 1000 })`. Custom events appear in the [Activity](/features/product-analytics/activity) feed and can be queried in the [Explorer](/features/product-analytics/explore).
+ Use [formo.track()](/data/events/track) to send custom events with any properties you need. For example: `formo.track('Swap Completed', { pair: 'ETH/USDC', token_in: 'ETH', token_out: 'USDC', amount_in: 1.5 })`. Custom events appear in the [Activity](/features/product-analytics/activity) feed and can be queried in the [Explorer](/features/product-analytics/explore).
Yes. The SDK provides built-in [consent management](#consent-management) with `optOutTracking()` and `optInTracking()` methods. Call `optOutTracking()` to stop all tracking for a user, and `optInTracking()` to re-enable it. Formo does not use third-party cookies, IP addresses, or device fingerprinting, so most jurisdictions do not require a cookie consent banner.
diff --git a/styles/config/vocabularies/Formo/accept.txt b/styles/config/vocabularies/Formo/accept.txt
new file mode 100644
index 0000000..43788ac
--- /dev/null
+++ b/styles/config/vocabularies/Formo/accept.txt
@@ -0,0 +1,68 @@
+Angular's
+Autocapture
+Autocaptured
+Beehiiv
+Bing
+Cloudfront
+Dailymotion
+Ethereum
+Farcaster
+Formo
+Formo's
+Genspark
+Kagi
+Kimi
+Naver
+OAuth
+Onchain
+Phind
+Pinterest
+Qwen
+SDK's
+SDKs
+Serverless
+Snapchat
+Solana
+Subresource
+Substack
+UTMs
+Uniswap
+Vercel
+Wagmi
+Wagmi's
+Wistia
+Yandex
+async
+autocapture
+autocaptured
+autocaptures
+autodetects
+backgrounding
+config
+crypto
+dApp
+dApps
+denylist
+ePrivacy
+enqueued
+esbuild
+formo
+globals
+hostname
+hostnames
+injectable
+leaderboards
+lightbulb
+logLevel
+middleware
+offchain
+onchain
+pageview
+polyfill
+serverless
+solana
+subpath
+summer_sale
+viem
+wagmi
+zustand