Skip to content

Commit 4d6cbe4

Browse files
authored
feat: add rybbit analytics to registry (#453)
1 parent 45a8b07 commit 4d6cbe4

File tree

4 files changed

+222
-0
lines changed

4 files changed

+222
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
title: Rybbit Analytics
3+
description: Use Rybbit Analytics in your Nuxt app.
4+
links:
5+
- label: Source
6+
icon: i-simple-icons-github
7+
to: https://github.com/nuxt/scripts/blob/main/src/runtime/registry/rybbit.ts
8+
size: xs
9+
---
10+
11+
[Rybbit Analytics](https://www.rybbit.io/) is a privacy-focused analytics solution for tracking user activity on your website without compromising your users' privacy.
12+
13+
The simplest way to load Rybbit Analytics globally in your Nuxt App is to use Nuxt config. Alternatively you can directly
14+
use the [useScriptRybbitAnalytics](#useScriptRybbitAnalytics) composable.
15+
16+
## Loading Globally
17+
18+
If you don't plan to send custom events you can use the [Environment overrides](https://nuxt.com/docs/getting-started/configuration#environment-overrides) to
19+
disable the script in development.
20+
21+
::code-group
22+
23+
```ts [Always enabled]
24+
export default defineNuxtConfig({
25+
scripts: {
26+
registry: {
27+
rybbitAnalytics: {
28+
siteId: 'YOUR_SITE_ID'
29+
}
30+
}
31+
}
32+
})
33+
```
34+
35+
```ts [Production only]
36+
export default defineNuxtConfig({
37+
$production: {
38+
scripts: {
39+
registry: {
40+
rybbitAnalytics: {
41+
siteId: 'YOUR_SITE_ID',
42+
}
43+
}
44+
}
45+
}
46+
})
47+
```
48+
49+
```ts [Environment Variables]
50+
export default defineNuxtConfig({
51+
scripts: {
52+
registry: {
53+
rybbitAnalytics: true,
54+
}
55+
},
56+
// you need to provide a runtime config to access the environment variables
57+
runtimeConfig: {
58+
public: {
59+
scripts: {
60+
rybbitAnalytics: {
61+
// .env
62+
// NUXT_PUBLIC_SCRIPTS_RYBBIT_ANALYTICS_SITE_ID=<your-site-id>
63+
siteId: ''
64+
},
65+
},
66+
},
67+
},
68+
})
69+
```
70+
71+
::
72+
73+
## useScriptRybbitAnalytics
74+
75+
The `useScriptRybbitAnalytics` composable lets you have fine-grain control over when and how Rybbit Analytics is loaded on your site.
76+
77+
```ts
78+
const rybbit = useScriptRybbitAnalytics({
79+
siteId: 'YOUR_SITE_ID'
80+
})
81+
```
82+
83+
Please follow the [Registry Scripts](/docs/guides/registry-scripts) guide to learn more about advanced usage.
84+
85+
### Self-hosted Rybbit Analytics
86+
87+
If you are using a self-hosted version of Rybbit Analytics, you can provide a custom script source:
88+
89+
```ts
90+
useScriptRybbitAnalytics({
91+
scriptInput: {
92+
src: 'https://your-rybbit-instance.com/api/script.js'
93+
}
94+
siteId: 'YOUR_SITE_ID'
95+
})
96+
```
97+
98+
### RybbitAnalyticsApi
99+
100+
```ts
101+
export interface RybbitAnalyticsApi {
102+
pageview: () => void
103+
event: (eventName: string, properties?: Record<string, any>) => void
104+
}
105+
```
106+
107+
### Config Schema
108+
109+
You must provide the options when setting up the script for the first time.
110+
111+
```ts
112+
export const RybbitAnalyticsOptions = object({
113+
siteId: string(), // required
114+
trackSpa: optional(boolean()),
115+
trackQuery: optional(boolean()),
116+
skipPatterns: optional(array(string())),
117+
maskPatterns: optional(array(string())),
118+
debounce: optional(number())
119+
})
120+
```
121+
122+
#### Configuration Options
123+
124+
- `siteId` (required): Your Rybbit Analytics site ID
125+
- `trackSpa`: Set to `false` to disable automatic pageview tracking for single page applications
126+
- `trackQuery`: Set to `false` to disable tracking of URL query strings
127+
- `skipPatterns`: Array of URL path patterns to ignore
128+
- `maskPatterns`: Array of URL path patterns to mask for privacy
129+
- `debounce`: Delay in milliseconds before tracking a pageview after URL changes
130+
131+
## Example
132+
133+
Using Rybbit Analytics only in production while tracking custom events.
134+
135+
::code-group
136+
137+
```vue [EventTracking.vue]
138+
<script setup lang="ts">
139+
const { proxy } = useScriptRybbitAnalytics()
140+
141+
// Track a pageview manually
142+
function trackPage() {
143+
proxy.rybbit.pageview()
144+
}
145+
146+
// Track a custom event
147+
function trackEvent() {
148+
proxy.rybbit.event('button_click', { buttonId: 'signup' })
149+
}
150+
</script>
151+
152+
<template>
153+
<div>
154+
<button @click="trackPage">
155+
Track Custom Page
156+
</button>
157+
<button @click="trackEvent">
158+
Track Custom Event
159+
</button>
160+
</div>
161+
</template>
162+
```
163+
164+
::

src/registry.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ export async function registry(resolve?: (path: string, opts?: ResolvePathOption
5858
from: await resolve('./runtime/registry/matomo-analytics'),
5959
},
6060
},
61+
{
62+
label: 'Rybbit Analytics',
63+
category: 'analytics',
64+
logo: `https://www.rybbit.io/rybbit.png`,
65+
import: {
66+
name: 'useScriptRybbitAnalytics',
67+
from: await resolve('./runtime/registry/rybbit-analytics'),
68+
},
69+
},
6170
{
6271
label: 'Segment',
6372
scriptBundling: (options?: SegmentInput) => {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { useRegistryScript } from '../utils'
2+
import { array, boolean, number, object, optional, string } from '#nuxt-scripts-validator'
3+
import type { RegistryScriptInput } from '#nuxt-scripts/types'
4+
5+
export const RybbitAnalyticsOptions = object({
6+
siteId: string(), // required
7+
trackSpa: optional(boolean()),
8+
trackQuery: optional(boolean()),
9+
skipPatterns: optional(array(string())),
10+
maskPatterns: optional(array(string())),
11+
debounce: optional(number()),
12+
})
13+
14+
export type RybbitAnalyticsInput = RegistryScriptInput<typeof RybbitAnalyticsOptions, false>
15+
16+
export interface RybbitAnalyticsApi {
17+
pageview: () => void
18+
event: (eventName: string, properties?: Record<string, any>) => void
19+
}
20+
21+
declare global {
22+
interface Window {
23+
rybbit: RybbitAnalyticsApi
24+
}
25+
}
26+
27+
export function useScriptRybbitAnalytics<T extends RybbitAnalyticsApi>(_options?: RybbitAnalyticsInput) {
28+
return useRegistryScript<T, typeof RybbitAnalyticsOptions>('rybbitAnalytics', (options) => {
29+
return {
30+
scriptInput: {
31+
'src': 'https://app.rybbit.io/api/script.js',
32+
'data-site-id': options?.siteId,
33+
'data-track-spa': options?.trackSpa,
34+
'data-track-query': options?.trackQuery,
35+
'data-skip-patterns': options?.skipPatterns ? JSON.stringify(options.skipPatterns) : undefined,
36+
'data-mask-patterns': options?.maskPatterns ? JSON.stringify(options.maskPatterns) : undefined,
37+
'data-debounce': options?.debounce ? options.debounce.toString() : undefined,
38+
},
39+
schema: import.meta.dev ? RybbitAnalyticsOptions : undefined,
40+
scriptOptions: {
41+
use() {
42+
return { rybbit: window.rybbit }
43+
},
44+
},
45+
}
46+
}, _options)
47+
}

src/runtime/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import type { CrispInput } from './registry/crisp'
2727
import type { GoogleAnalyticsInput } from './registry/google-analytics'
2828
import type { GoogleTagManagerInput } from './registry/google-tag-manager'
2929
import type { UmamiAnalyticsInput } from './registry/umami-analytics'
30+
import type { RybbitAnalyticsInput } from './registry/rybbit-analytics'
3031
import { object } from '#nuxt-scripts-validator'
3132

3233
export type WarmupStrategy = false | 'preload' | 'preconnect' | 'dns-prefetch'
@@ -139,6 +140,7 @@ export interface ScriptRegistry {
139140
hotjar?: HotjarInput
140141
intercom?: IntercomInput
141142
matomoAnalytics?: MatomoAnalyticsInput
143+
rybbitAnalytics?: RybbitAnalyticsInput
142144
segment?: SegmentInput
143145
stripe?: StripeInput
144146
xPixel?: XPixelInput

0 commit comments

Comments
 (0)