Skip to content

Commit a671824

Browse files
authored
feat: add Snapchat pixel to registry (#337)
1 parent ebcb328 commit a671824

File tree

7 files changed

+389
-0
lines changed

7 files changed

+389
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
---
2+
title: Snapchat Pixel
3+
description: Use Snapchat Pixel 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/snapchat-pixel.ts
8+
size: xs
9+
---
10+
11+
[Snapchat Pixel](https://businesshelp.snapchat.com/s/article/snap-pixel-about){:target="_blank"} lets you measure the crossdevice impact for your Snapchat ad campaigns.
12+
13+
Nuxt Scripts provides a registry script composable `useScriptSnapchatPixel` to easily integrate Snapchat Pixel in your Nuxt app.
14+
15+
### Nuxt Config Setup
16+
17+
The simplest way to load Snpachat Pixel globally in your Nuxt App is to use Nuxt config. Alternatively you can directly
18+
use the [useScriptSnapchatPixel](#useScriptSnapchatPixel) composable.
19+
20+
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
21+
disable the script in development.
22+
23+
::code-group
24+
25+
```ts [Always enabled]
26+
export default defineNuxtConfig({
27+
scripts: {
28+
registry: {
29+
snapchatPixel: {
30+
id: 'YOUR_ID'
31+
}
32+
}
33+
}
34+
})
35+
```
36+
37+
```ts [Production only]
38+
export default defineNuxtConfig({
39+
$production: {
40+
scripts: {
41+
registry: {
42+
snapchatPixel: {
43+
id: 'YOUR_ID',
44+
}
45+
}
46+
}
47+
}
48+
})
49+
```
50+
51+
::
52+
53+
#### With Environment Variables
54+
55+
If you prefer to configure your id using environment variables.
56+
57+
```ts [nuxt.config.ts]
58+
export default defineNuxtConfig({
59+
scripts: {
60+
registry: {
61+
snapchatPixel: true,
62+
}
63+
},
64+
// you need to provide a runtime config to access the environment variables
65+
runtimeConfig: {
66+
public: {
67+
scripts: {
68+
snapchatPixel: {
69+
id: '', // NUXT_PUBLIC_SCRIPTS_SNAPCHAT_PIXEL_ID
70+
},
71+
},
72+
},
73+
},
74+
})
75+
```
76+
77+
```text [.env]
78+
NUXT_PUBLIC_SCRIPTS_SNAPCHAT_PIXEL_ID=<YOUR_ID>
79+
```
80+
81+
## useScriptSnapchatPixel
82+
83+
The `useScriptSnapchatPixel` composable lets you have fine-grain control over when and how Snapchat Pixel is loaded on your site.
84+
85+
```ts
86+
const { proxy } = useScriptSnapchatPixel({
87+
id: 'YOUR_ID',
88+
user_email: 'USER_EMAIL'
89+
})
90+
// example
91+
proxy.snaptr('track', 'PURCHASE', {
92+
currency: 'USD',
93+
price: 120.10,
94+
transaction_id: '11111'
95+
})
96+
```
97+
98+
Please follow the [Registry Scripts](/docs/guides/registry-scripts) guide to learn more about advanced usage.
99+
100+
### SnapchatPixelApi
101+
102+
```ts
103+
export interface SnapPixelApi {
104+
snaptr: SnapTrFns & {
105+
push: SnapTrFns
106+
loaded: boolean
107+
version: string
108+
queue: any[]
109+
}
110+
_snaptr: SnapPixelApi['snaptr']
111+
handleRequest?: SnapTrFns
112+
}
113+
type StandardEvents = 'PAGE_VIEW' | 'VIEW_CONTENT' | 'ADD_CART' | 'SIGN_UP' | 'SAVE' | 'START_CHECKOUT' | 'APP_OPEN' | 'ADD_BILLING' | 'SEARCH' | 'SUBSCRIBE' | 'AD_CLICK' | 'AD_VIEW' | 'COMPLETE_TUTORIAL' | 'LEVEL_COMPLETE' | 'INVITE' | 'LOGIN' | 'SHARE' | 'RESERVE' | 'ACHIEVEMENT_UNLOCKED' | 'ADD_TO_WISHLIST' | 'SPENT_CREDITS' | 'RATE' | 'START_TRIAL' | 'LIST_VIEW'
114+
type SnapTrFns =
115+
((event: 'track', eventName: StandardEvents | '', data?: EventObjectProperties) => void) &
116+
((event: 'init', id: string, data?: Record<string, any>) => void) &
117+
((event: 'init', id: string, data?: InitObjectProperties) => void) &
118+
((event: string, ...params: any[]) => void)
119+
interface EventObjectProperties {
120+
price?: number
121+
client_dedup_id?: string
122+
currency?: string
123+
transaction_id?: string
124+
item_ids?: string[]
125+
item_category?: string
126+
description?: string
127+
search_string?: string
128+
number_items?: number
129+
payment_info_available?: 0 | 1
130+
sign_up_method?: string
131+
success?: 0 | 1
132+
brands?: string[]
133+
delivery_method?: 'in_store' | 'curbside' | 'delivery'
134+
customer_status?: 'new' | 'returning' | 'reactivated'
135+
event_tag?: string
136+
[key: string]: any
137+
}
138+
interface InitObjectProperties {
139+
user_email?: string
140+
ip_address?: string
141+
user_phone_number?: string
142+
user_hashed_email?: string
143+
user_hashed_phone_number?: string
144+
firstname?: string
145+
lastname?: string
146+
geo_city?: string
147+
geo_region?: string
148+
geo_postal_code?: string
149+
geo_country?: string
150+
age?: string
151+
}
152+
```
153+
154+
### Config Schema
155+
156+
You must provide the options when setting up the script for the first time.
157+
158+
```ts
159+
export const SnapTrPixelOptions = object({
160+
id: string(),
161+
trackPageView: optional(boolean()),
162+
user_email: optional(string()),
163+
ip_address: optional(string()),
164+
user_phone_number: optional(string()),
165+
user_hashed_email: optional(string()),
166+
user_hashed_phone_number: optional(string()),
167+
firstname: optional(string()),
168+
lastname: optional(string()),
169+
geo_city: optional(string()),
170+
geo_region: optional(string()),
171+
geo_postal_code: optional(string()),
172+
geo_country: optional(string()),
173+
age: optional(string()),
174+
})
175+
```
176+
177+
## Example
178+
179+
Using Snapchat Pixel only in production while using `snaptr` to send a conversion event.
180+
181+
::code-group
182+
183+
```vue [ConversionButton.vue]
184+
<script setup lang="ts">
185+
const { proxy } = useScriptSnapchatPixel()
186+
187+
// noop in development, ssr
188+
// just works in production, client
189+
function sendConversion() {
190+
proxy.snaptr('track', 'PURCHASE', {
191+
currency: 'USD',
192+
price: 120.10,
193+
transaction_id: '11111'
194+
})
195+
}
196+
</script>
197+
198+
<template>
199+
<div>
200+
<button @click="sendConversion">
201+
Send Conversion
202+
</button>
203+
</div>
204+
</template>
205+
```
206+
207+
::

playground/pages/index.vue

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ const thirdParties = [
5858
name: 'Segment',
5959
path: '/third-parties/segment',
6060
},
61+
{
62+
name: 'Snapchat',
63+
path: '/third-parties/snapchat/nuxt-scripts',
64+
},
6165
]
6266
6367
const thirdPartyComponents = [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script lang="ts" setup>
2+
import { useHead } from '#imports'
3+
4+
useHead({
5+
script: [
6+
{ innerHTML: '(function(e,t,n){if(e.snaptr)return;var a=e.snaptr=function()\n'
7+
+ '{a.handleRequest?a.handleRequest.apply(a,arguments):a.queue.push(arguments)};\n'
8+
+ 'a.queue=[];var s=\'script\';r=t.createElement(s);r.async=!0;\n'
9+
+ 'r.src=n;var u=t.getElementsByTagName(s)[0];\n'
10+
+ 'u.parentNode.insertBefore(r,u);})(window,document, \'https://sc-static.net/scevent.min.js\');\n'
11+
+ 'window.snaptr(\'init\', \'2295cbcc-cb3f-4727-8c09-1133b742722c\');',
12+
},
13+
],
14+
})
15+
16+
function triggerEvent() {
17+
window.snaptr('track', 'PAGE_VIEW')
18+
}
19+
</script>
20+
21+
<template>
22+
<div>
23+
<UButton @click="() => triggerEvent()">
24+
Trigger Event
25+
</UButton>
26+
</div>
27+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts" setup>
2+
import { useHead, useScriptSnapchatPixel } from '#imports'
3+
4+
useHead({
5+
title: 'Snapchat Pixel',
6+
})
7+
8+
// composables return the underlying api as a proxy object and the script state
9+
const { status, snaptr } = useScriptSnapchatPixel({ id: '2295cbcc-cb3f-4727-8c09-1133b742722c' })
10+
// this will be triggered once the script is ready async
11+
12+
function triggerEvent() {
13+
snaptr('track', 'PAGE_VIEW')
14+
}
15+
</script>
16+
17+
<template>
18+
<div>
19+
<ClientOnly>
20+
<div>
21+
status: {{ status }}
22+
</div>
23+
<UButton @click="triggerEvent">
24+
Trigger Event
25+
</UButton>
26+
</ClientOnly>
27+
</div>
28+
</template>

src/registry.ts

+10
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ export const registry: (resolve?: (s: string) => string) => RegistryScripts = (r
9292
from: resolve('./runtime/registry/x-pixel'),
9393
},
9494
},
95+
{
96+
label: 'Snapchat Pixel',
97+
src: 'https://sc-static.net/scevent.min.js',
98+
category: 'tracking',
99+
logo: '<svg width="50" height="50" viewBox="147.353 39.286 514.631 514.631" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><path style="fill:#FFFC00;" d="M147.553,423.021v0.023c0.308,11.424,0.403,22.914,2.33,34.268 c2.042,12.012,4.961,23.725,10.53,34.627c7.529,14.756,17.869,27.217,30.921,37.396c9.371,7.309,19.608,13.111,30.94,16.771 c16.524,5.33,33.571,7.373,50.867,7.473c10.791,0.068,21.575,0.338,32.37,0.293c78.395-0.33,156.792,0.566,235.189-0.484 c10.403-0.141,20.636-1.41,30.846-3.277c19.569-3.582,36.864-11.932,51.661-25.133c17.245-15.381,28.88-34.205,34.132-56.924 c3.437-14.85,4.297-29.916,4.444-45.035v-3.016c0-1.17-0.445-256.892-0.486-260.272c-0.115-9.285-0.799-18.5-2.54-27.636 c-2.117-11.133-5.108-21.981-10.439-32.053c-5.629-10.641-12.68-20.209-21.401-28.57c-13.359-12.81-28.775-21.869-46.722-26.661 c-16.21-4.327-32.747-5.285-49.405-5.27c-0.027-0.004-0.09-0.173-0.094-0.255H278.56c-0.005,0.086-0.008,0.172-0.014,0.255 c-9.454,0.173-18.922,0.102-28.328,1.268c-10.304,1.281-20.509,3.21-30.262,6.812c-15.362,5.682-28.709,14.532-40.11,26.347 c-12.917,13.386-22.022,28.867-26.853,46.894c-4.31,16.084-5.248,32.488-5.271,49.008"/><path style="fill:#FFFFFF;" d="M407.001,473.488c-1.068,0-2.087-0.039-2.862-0.076c-0.615,0.053-1.25,0.076-1.886,0.076 c-22.437,0-37.439-10.607-50.678-19.973c-9.489-6.703-18.438-13.031-28.922-14.775c-5.149-0.854-10.271-1.287-15.22-1.287 c-8.917,0-15.964,1.383-21.109,2.389c-3.166,0.617-5.896,1.148-8.006,1.148c-2.21,0-4.895-0.49-6.014-4.311 c-0.887-3.014-1.523-5.934-2.137-8.746c-1.536-7.027-2.65-11.316-5.281-11.723c-28.141-4.342-44.768-10.738-48.08-18.484 c-0.347-0.814-0.541-1.633-0.584-2.443c-0.129-2.309,1.501-4.334,3.777-4.711c22.348-3.68,42.219-15.492,59.064-35.119 c13.049-15.195,19.457-29.713,20.145-31.316c0.03-0.072,0.065-0.148,0.101-0.217c3.247-6.588,3.893-12.281,1.926-16.916 c-3.626-8.551-15.635-12.361-23.58-14.882c-1.976-0.625-3.845-1.217-5.334-1.808c-7.043-2.782-18.626-8.66-17.083-16.773 c1.124-5.916,8.949-10.036,15.273-10.036c1.756,0,3.312,0.308,4.622,0.923c7.146,3.348,13.575,5.045,19.104,5.045 c6.876,0,10.197-2.618,11-3.362c-0.198-3.668-0.44-7.546-0.674-11.214c0-0.004-0.005-0.048-0.005-0.048 c-1.614-25.675-3.627-57.627,4.546-75.95c24.462-54.847,76.339-59.112,91.651-59.112c0.408,0,6.674-0.062,6.674-0.062 c0.283-0.005,0.59-0.009,0.908-0.009c15.354,0,67.339,4.27,91.816,59.15c8.173,18.335,6.158,50.314,4.539,76.016l-0.076,1.23 c-0.222,3.49-0.427,6.793-0.6,9.995c0.756,0.696,3.795,3.096,9.978,3.339c5.271-0.202,11.328-1.891,17.998-5.014 c2.062-0.968,4.345-1.169,5.895-1.169c2.343,0,4.727,0.456,6.714,1.285l0.106,0.041c5.66,2.009,9.367,6.024,9.447,10.242 c0.071,3.932-2.851,9.809-17.223,15.485c-1.472,0.583-3.35,1.179-5.334,1.808c-7.952,2.524-19.951,6.332-23.577,14.878 c-1.97,4.635-1.322,10.326,1.926,16.912c0.036,0.072,0.067,0.145,0.102,0.221c1,2.344,25.205,57.535,79.209,66.432 c2.275,0.379,3.908,2.406,3.778,4.711c-0.048,0.828-0.248,1.656-0.598,2.465c-3.289,7.703-19.915,14.09-48.064,18.438 c-2.642,0.408-3.755,4.678-5.277,11.668c-0.63,2.887-1.271,5.717-2.146,8.691c-0.819,2.797-2.641,4.164-5.567,4.164h-0.441 c-1.905,0-4.604-0.346-8.008-1.012c-5.95-1.158-12.623-2.236-21.109-2.236c-4.948,0-10.069,0.434-15.224,1.287 c-10.473,1.744-19.421,8.062-28.893,14.758C444.443,462.88,429.436,473.488,407.001,473.488"/><path style="fill:#020202;" d="M408.336,124.235c14.455,0,64.231,3.883,87.688,56.472c7.724,17.317,5.744,48.686,4.156,73.885 c-0.248,3.999-0.494,7.875-0.694,11.576l-0.084,1.591l1.062,1.185c0.429,0.476,4.444,4.672,13.374,5.017l0.144,0.008l0.15-0.003 c5.904-0.225,12.554-2.059,19.776-5.442c1.064-0.498,2.48-0.741,3.978-0.741c1.707,0,3.521,0.321,5.017,0.951l0.226,0.09 c3.787,1.327,6.464,3.829,6.505,6.093c0.022,1.28-0.935,5.891-14.359,11.194c-1.312,0.518-3.039,1.069-5.041,1.7 c-8.736,2.774-21.934,6.96-26.376,17.427c-2.501,5.896-1.816,12.854,2.034,20.678c1.584,3.697,26.52,59.865,82.631,69.111 c-0.011,0.266-0.079,0.557-0.229,0.9c-0.951,2.24-6.996,9.979-44.612,15.783c-5.886,0.902-7.328,7.5-9,15.17 c-0.604,2.746-1.218,5.518-2.062,8.381c-0.258,0.865-0.306,0.914-1.233,0.914c-0.128,0-0.278,0-0.442,0 c-1.668,0-4.2-0.346-7.135-0.922c-5.345-1.041-12.647-2.318-21.982-2.318c-5.21,0-10.577,0.453-15.962,1.352 c-11.511,1.914-20.872,8.535-30.786,15.543c-13.314,9.408-27.075,19.143-48.071,19.143c-0.917,0-1.812-0.031-2.709-0.076 l-0.236-0.01l-0.237,0.018c-0.515,0.045-1.034,0.068-1.564,0.068c-20.993,0-34.76-9.732-48.068-19.143 c-9.916-7.008-19.282-13.629-30.791-15.543c-5.38-0.896-10.752-1.352-15.959-1.352c-9.333,0-16.644,1.428-21.978,2.471 c-2.935,0.574-5.476,1.066-7.139,1.066c-1.362,0-1.388-0.08-1.676-1.064c-0.844-2.865-1.461-5.703-2.062-8.445 c-1.676-7.678-3.119-14.312-9.002-15.215c-37.613-5.809-43.659-13.561-44.613-15.795c-0.149-0.352-0.216-0.652-0.231-0.918 c56.11-9.238,81.041-65.408,82.63-69.119c3.857-7.818,4.541-14.775,2.032-20.678c-4.442-10.461-17.638-14.653-26.368-17.422 c-2.007-0.635-3.735-1.187-5.048-1.705c-11.336-4.479-14.823-8.991-14.305-11.725c0.601-3.153,6.067-6.359,10.837-6.359 c1.072,0,2.012,0.173,2.707,0.498c7.747,3.631,14.819,5.472,21.022,5.472c9.751,0,14.091-4.537,14.557-5.055l1.057-1.182 l-0.085-1.583c-0.197-3.699-0.44-7.574-0.696-11.565c-1.583-25.205-3.563-56.553,4.158-73.871 c23.37-52.396,72.903-56.435,87.525-56.435c0.36,0,6.717-0.065,6.717-0.065C407.744,124.239,408.033,124.235,408.336,124.235 M408.336,115.197h-0.017c-0.333,0-0.646,0-0.944,0.004c-2.376,0.024-6.282,0.062-6.633,0.066c-8.566,0-25.705,1.21-44.115,9.336 c-10.526,4.643-19.994,10.921-28.14,18.66c-9.712,9.221-17.624,20.59-23.512,33.796c-8.623,19.336-6.576,51.905-4.932,78.078 l0.006,0.041c0.176,2.803,0.361,5.73,0.53,8.582c-1.265,0.581-3.316,1.194-6.339,1.194c-4.864,0-10.648-1.555-17.187-4.619 c-1.924-0.896-4.12-1.349-6.543-1.349c-3.893,0-7.997,1.146-11.557,3.239c-4.479,2.63-7.373,6.347-8.159,10.468 c-0.518,2.726-0.493,8.114,5.492,13.578c3.292,3.008,8.128,5.782,14.37,8.249c1.638,0.645,3.582,1.261,5.641,1.914 c7.145,2.271,17.959,5.702,20.779,12.339c1.429,3.365,0.814,7.793-1.823,13.145c-0.069,0.146-0.138,0.289-0.201,0.439 c-0.659,1.539-6.807,15.465-19.418,30.152c-7.166,8.352-15.059,15.332-23.447,20.752c-10.238,6.617-21.316,10.943-32.923,12.855 c-4.558,0.748-7.813,4.809-7.559,9.424c0.078,1.33,0.39,2.656,0.931,3.939c0.004,0.008,0.009,0.016,0.013,0.023 c1.843,4.311,6.116,7.973,13.063,11.203c8.489,3.943,21.185,7.26,37.732,9.855c0.836,1.59,1.704,5.586,2.305,8.322 c0.629,2.908,1.285,5.898,2.22,9.074c1.009,3.441,3.626,7.553,10.349,7.553c2.548,0,5.478-0.574,8.871-1.232 c4.969-0.975,11.764-2.305,20.245-2.305c4.702,0,9.575,0.414,14.48,1.229c9.455,1.574,17.606,7.332,27.037,14 c13.804,9.758,29.429,20.803,53.302,20.803c0.651,0,1.304-0.021,1.949-0.066c0.789,0.037,1.767,0.066,2.799,0.066 c23.88,0,39.501-11.049,53.29-20.799l0.022-0.02c9.433-6.66,17.575-12.41,27.027-13.984c4.903-0.814,9.775-1.229,14.479-1.229 c8.102,0,14.517,1.033,20.245,2.15c3.738,0.736,6.643,1.09,8.872,1.09l0.218,0.004h0.226c4.917,0,8.53-2.699,9.909-7.422 c0.916-3.109,1.57-6.029,2.215-8.986c0.562-2.564,1.46-6.674,2.296-8.281c16.558-2.6,29.249-5.91,37.739-9.852 c6.931-3.215,11.199-6.873,13.053-11.166c0.556-1.287,0.881-2.621,0.954-3.979c0.261-4.607-2.999-8.676-7.56-9.424 c-51.585-8.502-74.824-61.506-75.785-63.758c-0.062-0.148-0.132-0.295-0.205-0.438c-2.637-5.354-3.246-9.777-1.816-13.148 c2.814-6.631,13.621-10.062,20.771-12.332c2.07-0.652,4.021-1.272,5.646-1.914c7.039-2.78,12.07-5.796,15.389-9.221 c3.964-4.083,4.736-7.995,4.688-10.555c-0.121-6.194-4.856-11.698-12.388-14.393c-2.544-1.052-5.445-1.607-8.399-1.607 c-2.011,0-4.989,0.276-7.808,1.592c-6.035,2.824-11.441,4.368-16.082,4.588c-2.468-0.125-4.199-0.66-5.32-1.171 c0.141-2.416,0.297-4.898,0.458-7.486l0.067-1.108c1.653-26.19,3.707-58.784-4.92-78.134c-5.913-13.253-13.853-24.651-23.604-33.892 c-8.178-7.744-17.678-14.021-28.242-18.661C434.052,116.402,416.914,115.197,408.336,115.197"/><rect x="147.553" y="39.443" style="fill:none;" width="514.231" height="514.23"/></svg>',
100+
import: {
101+
name: 'useScriptSnapchatPixel',
102+
from: resolve('./runtime/registry/snapchat-pixel'),
103+
},
104+
},
95105
// ads
96106
{
97107
label: 'Google Adsense',

0 commit comments

Comments
 (0)