Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Snapchat pixel to registry #337

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions docs/content/scripts/tracking/snapchat-pixel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
title: Snapchat Pixel
description: Use Snapchat Pixel in your Nuxt app.
links:
- label: Source
icon: i-simple-icons-github
to: https://github.com/nuxt/scripts/blob/main/src/runtime/registry/snapchat-pixel.ts
size: xs
---

[Snapchat Pixel](https://businesshelp.snapchat.com/s/article/snap-pixel-about){:target="_blank"} lets you measure the crossdevice impact for your Snapchat ad campaigns.

Nuxt Scripts provides a registry script composable `useScriptSnapchatPixel` to easily integrate Snapchat Pixel in your Nuxt app.

### Nuxt Config Setup

The simplest way to load Snpachat Pixel globally in your Nuxt App is to use Nuxt config. Alternatively you can directly
use the [useScriptSnapchatPixel](#useScriptSnapchatPixel) composable.

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
disable the script in development.

::code-group

```ts [Always enabled]
export default defineNuxtConfig({
scripts: {
registry: {
snapchatPixel: {
id: 'YOUR_ID'
}
}
}
})
```

```ts [Production only]
export default defineNuxtConfig({
$production: {
scripts: {
registry: {
snapchatPixel: {
id: 'YOUR_ID',
}
}
}
}
})
```

::

#### With Environment Variables

If you prefer to configure your id using environment variables.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
scripts: {
registry: {
snapchatPixel: true,
}
},
// you need to provide a runtime config to access the environment variables
runtimeConfig: {
public: {
scripts: {
snapchatPixel: {
id: '', // NUXT_PUBLIC_SCRIPTS_SNAPCHAT_PIXEL_ID
},
},
},
},
})
```

```text [.env]
NUXT_PUBLIC_SCRIPTS_SNAPCHAT_PIXEL_ID=<YOUR_ID>
```

## useScriptSnapchatPixel

The `useScriptSnapchatPixel` composable lets you have fine-grain control over when and how Snapchat Pixel is loaded on your site.

```ts
const { proxy } = useScriptSnapchatPixel({
id: 'YOUR_ID',
user_email: 'USER_EMAIL'
})
// example
proxy.snaptr('track', 'PURCHASE', {
currency: 'USD',
price: 120.10,
transaction_id: '11111'
})
```

Please follow the [Registry Scripts](/docs/guides/registry-scripts) guide to learn more about advanced usage.

### SnapchatPixelApi

```ts
export interface SnapPixelApi {
snaptr: SnapTrFns & {
push: SnapTrFns
loaded: boolean
version: string
queue: any[]
}
_snaptr: SnapPixelApi['snaptr']
handleRequest?: SnapTrFns
}
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'
type SnapTrFns =
((event: 'track', eventName: StandardEvents | '', data?: EventObjectProperties) => void) &
((event: 'init', id: string, data?: Record<string, any>) => void) &
((event: 'init', id: string, data?: InitObjectProperties) => void) &
((event: string, ...params: any[]) => void)
interface EventObjectProperties {
price?: number
client_dedup_id?: string
currency?: string
transaction_id?: string
item_ids?: string[]
item_category?: string
description?: string
search_string?: string
number_items?: number
payment_info_available?: 0 | 1
sign_up_method?: string
success?: 0 | 1
brands?: string[]
delivery_method?: 'in_store' | 'curbside' | 'delivery'
customer_status?: 'new' | 'returning' | 'reactivated'
event_tag?: string
[key: string]: any
}
interface InitObjectProperties {
user_email?: string
ip_address?: string
user_phone_number?: string
user_hashed_email?: string
user_hashed_phone_number?: string
firstname?: string
lastname?: string
geo_city?: string
geo_region?: string
geo_postal_code?: string
geo_country?: string
age?: string
}
```

### Config Schema

You must provide the options when setting up the script for the first time.

```ts
export const SnapTrPixelOptions = object({
id: string(),
trackPageView: optional(boolean()),
user_email: optional(string()),
ip_address: optional(string()),
user_phone_number: optional(string()),
user_hashed_email: optional(string()),
user_hashed_phone_number: optional(string()),
firstname: optional(string()),
lastname: optional(string()),
geo_city: optional(string()),
geo_region: optional(string()),
geo_postal_code: optional(string()),
geo_country: optional(string()),
age: optional(string()),
})
```

## Example

Using Snapchat Pixel only in production while using `snaptr` to send a conversion event.

::code-group

```vue [ConversionButton.vue]
<script setup lang="ts">
const { proxy } = useScriptSnapchatPixel()

// noop in development, ssr
// just works in production, client
function sendConversion() {
proxy.snaptr('track', 'PURCHASE', {
currency: 'USD',
price: 120.10,
transaction_id: '11111'
})
}
</script>

<template>
<div>
<button @click="sendConversion">
Send Conversion
</button>
</div>
</template>
```

::
4 changes: 4 additions & 0 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const thirdParties = [
name: 'Segment',
path: '/third-parties/segment',
},
{
name: 'Snapchat',
path: '/third-parties/snapchat/nuxt-scripts',
},
]

const thirdPartyComponents = [
Expand Down
27 changes: 27 additions & 0 deletions playground/pages/third-parties/snapchat/default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<script lang="ts" setup>
import { useHead } from '#imports'

useHead({
script: [
{ innerHTML: '(function(e,t,n){if(e.snaptr)return;var a=e.snaptr=function()\n'
+ '{a.handleRequest?a.handleRequest.apply(a,arguments):a.queue.push(arguments)};\n'
+ 'a.queue=[];var s=\'script\';r=t.createElement(s);r.async=!0;\n'
+ 'r.src=n;var u=t.getElementsByTagName(s)[0];\n'
+ 'u.parentNode.insertBefore(r,u);})(window,document, \'https://sc-static.net/scevent.min.js\');\n'
+ 'window.snaptr(\'init\', \'2295cbcc-cb3f-4727-8c09-1133b742722c\');',
},
],
})

function triggerEvent() {
window.snaptr('track', 'PAGE_VIEW')
}
</script>

<template>
<div>
<UButton @click="() => triggerEvent()">
Trigger Event
</UButton>
</div>
</template>
28 changes: 28 additions & 0 deletions playground/pages/third-parties/snapchat/nuxt-scripts.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script lang="ts" setup>
import { useHead, useScriptSnapchatPixel } from '#imports'

useHead({
title: 'Snapchat Pixel',
})

// composables return the underlying api as a proxy object and the script state
const { status, snaptr } = useScriptSnapchatPixel({ id: '2295cbcc-cb3f-4727-8c09-1133b742722c' })
// this will be triggered once the script is ready async

function triggerEvent() {
snaptr('track', 'PAGE_VIEW')
}
</script>

<template>
<div>
<ClientOnly>
<div>
status: {{ status }}
</div>
<UButton @click="triggerEvent">
Trigger Event
</UButton>
</ClientOnly>
</div>
</template>
10 changes: 10 additions & 0 deletions src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ export const registry: (resolve?: (s: string) => string) => RegistryScripts = (r
from: resolve('./runtime/registry/x-pixel'),
},
},
{
label: 'Snapchat Pixel',
src: 'https://sc-static.net/scevent.min.js',
category: 'tracking',
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>',
import: {
name: 'useScriptSnapchatPixel',
from: resolve('./runtime/registry/snapchat-pixel'),
},
},
// ads
{
label: 'Google Adsense',
Expand Down
Loading
Loading