Skip to content

Commit 6ab44ce

Browse files
committed
feat(refactor): Bring inline with Google Analytics
1 parent 9793b84 commit 6ab44ce

13 files changed

+221
-93
lines changed

.eslintignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
src/functions.js
4+
example/main.js

.gitignore

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
.DS_Store
22
node_modules
3-
yarn.lock
4-
package-lock.json
5-
index.js
6-
index.mjs
3+
/dist/
4+
public/build

example/App.svelte

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script>
2+
import { FacebookPixel } from '../src/index.js'
3+
import { Router, Route, Link } from 'svelte-routing'
4+
import Home from './pages/home.svelte'
5+
import About from './pages/about.svelte'
6+
export let url = ''
7+
</script>
8+
9+
<FacebookPixel pixels={[ 'ABC123' ]} />
10+
11+
<Router {url}>
12+
<nav>
13+
<Link to="/">Home</Link>
14+
<Link to="about">About</Link>
15+
</nav>
16+
<div>
17+
<Route path="about" component="{About}" />
18+
<Route path="/"><Home /></Route>
19+
</div>
20+
</Router>
21+

example/main.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import App from './App.svelte'
2+
3+
const app = new App({
4+
target: document.body
5+
})
6+
7+
export default app
8+
9+
if (import.meta.hot) {
10+
import.meta.hot.dispose(() => {
11+
app.$destroy()
12+
})
13+
import.meta.hot.accept()
14+
}

example/pages/about.svelte

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script>
2+
const pageName = 'About Page'
3+
</script>
4+
5+
<svelte:head>
6+
<title>About</title>
7+
</svelte:head>
8+
9+
<main>
10+
<h1>{pageName}!</h1>
11+
<p>Welcome this is my <b>{pageName}</b></p>
12+
</main>

example/pages/home.svelte

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<script>
2+
import { fb } from '../../src/index.js'
3+
4+
const currency = 'SvelteBucks'
5+
const items = [ { id: 'prd-1', name: 'Svelte Swag', quantity: 1, price: 10 } ]
6+
</script>
7+
8+
<svelte:head>
9+
<title>Home</title>
10+
</svelte:head>
11+
12+
<main>
13+
<h1>Home Page</h1>
14+
<p>Welcome this is my website</p>
15+
16+
<button on:click={e => fb.trackCustom('Voucher', { currency, discount: 50 })}>
17+
Earn 50 SvelteBucks
18+
</button>
19+
<button on:click={e => fb.track('Lead', { currency, items, cost: 10 })}>
20+
Add Swag to Cart
21+
</button>
22+
<button on:click={e => fb.trackSingle('ABC123', 'Purchase', { currency, items, cost: 10 })}>
23+
Purchase Swag
24+
</button>
25+
</main>

package.json

+31-15
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,42 @@
11
{
2-
"name": "@beyonk/svelte-facebook-pixel",
3-
"version": "2.1.1",
4-
"svelte": "src/FacebookPixel.svelte",
5-
"module": "index.mjs",
6-
"main": "index.js",
2+
"name": "@beyonk/svelte-google-analytics",
3+
"svelte": "src/index.js",
4+
"module": "dist/index.mjs",
5+
"main": "dist/index.js",
76
"scripts": {
7+
"dev": "WATCH=true nollup -c --hot --port 5000 --content-base ./public -s",
88
"build": "rollup -c",
9-
"prepublishOnly": "npm run build"
9+
"prepublishOnly": "npm run build",
10+
"lint": "eslint . --ext .svelte,.html,.js"
1011
},
1112
"devDependencies": {
12-
"rollup": "^2.0.5",
13-
"rollup-plugin-svelte": "^5.1.1",
14-
"svelte": "^3.19.2"
13+
"@beyonk/async-script-loader": "^2.2.1",
14+
"@beyonk/eslint-config": "^4.2.0",
15+
"@rollup/plugin-node-resolve": "^9.0.0",
16+
"cheerio": "^1.0.0-rc.3",
17+
"eslint": "^7.9.0",
18+
"eslint-plugin-svelte3": "^2.7.3",
19+
"just-camel-case": "^4.0.2",
20+
"just-flatten": "^1.0.0",
21+
"node-fetch": "^2.6.1",
22+
"nollup": "^0.13.9",
23+
"rollup": "^2.26.6",
24+
"rollup-plugin-hot": "^0.1.0",
25+
"rollup-plugin-svelte": "^6.0.0",
26+
"rollup-plugin-svelte-hot": "^0.10.0",
27+
"svelte": "^3.24.1",
28+
"svelte-feather-icons": "^3.2.2",
29+
"svelte-routing": "^1.4.2"
30+
},
31+
"eslintConfig": {
32+
"extends": "@beyonk/eslint-config/svelte"
1533
},
1634
"keywords": [
17-
"svelte",
18-
"facebook",
19-
"tracking"
35+
"svelte"
2036
],
2137
"files": [
2238
"src",
23-
"index.mjs",
24-
"index.js"
25-
]
39+
"dist"
40+
],
41+
"version": "2.5.1"
2642
}

public/index.html

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset='utf-8'>
5+
<meta name='viewport' content='width=device-width,initial-scale=1'>
6+
<link href="https://fonts.googleapis.com/css2?family=Catamaran:wght@500&display=swap" rel="stylesheet">
7+
<script defer src='build/bundle.js'></script>
8+
</head>
9+
</html>

rollup.config.js

+35-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,39 @@
1-
import svelte from 'rollup-plugin-svelte';
2-
import pkg from './package.json';
1+
import pkg from './package.json'
2+
import svelte from 'rollup-plugin-svelte-hot'
3+
import resolve from '@rollup/plugin-node-resolve'
4+
import hmr from 'rollup-plugin-hot'
5+
6+
const dev = process.env.WATCH
37

48
const name = pkg.name
5-
.replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3')
6-
.replace(/^\w/, m => m.toUpperCase())
7-
.replace(/-\w/g, m => m[1].toUpperCase());
9+
.replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3')
10+
.replace(/^\w/, m => m.toUpperCase())
11+
.replace(/-\w/g, m => m[1].toUpperCase())
812

913
export default {
10-
input: 'src/FacebookPixel.svelte',
11-
output: [
12-
{ file: pkg.module, 'format': 'es' },
13-
{ file: pkg.main, 'format': 'umd', name }
14-
],
15-
plugins: [
16-
svelte()
17-
]
18-
};
14+
input: dev ? 'example/main.js' : 'src/index.js',
15+
output: dev ? {
16+
sourcemap: true,
17+
format: 'iife',
18+
name: 'app',
19+
file: 'public/build/bundle.js'
20+
} : [
21+
{ file: pkg.module, format: 'es' },
22+
{ file: pkg.main, format: 'umd', name }
23+
],
24+
plugins: [
25+
svelte(dev ? {
26+
dev: true,
27+
hot: {
28+
optimistic: true,
29+
noPreserveState: false
30+
}
31+
} : {}),
32+
resolve(),
33+
dev && hmr({
34+
public: 'example',
35+
inMemory: true,
36+
compatModuleHot: true
37+
})
38+
]
39+
}

src/FacebookPixel.svelte

+37-60
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,52 @@
11
<script>
2-
export let id
2+
import { onMount } from 'svelte'
3+
import loader from '@beyonk/async-script-loader'
4+
import { queue } from './queue.js'
5+
36
export let enabled = true
4-
export let version = 'v3.1'
5-
let pixels
7+
export let pixels = []
8+
69
let _fbq
710
8-
export function enable () {
9-
mount()
11+
onMount(() => {
12+
if (!enabled) { return }
1013
init()
11-
track()
14+
})
15+
16+
export function init () {
17+
loader(
18+
[
19+
{
20+
type: 'script',
21+
url: 'https://connect.facebook.net/en_US/fbevents.js'
22+
}
23+
],
24+
test,
25+
callback
26+
)
1227
}
1328
14-
function mount () {
15-
if (window['fbq']) {
16-
_fbq = window['fbq']
17-
return
18-
}
29+
function test () {
30+
return Boolean(window.dataLayer).valueOf() && Array.isArray(window.dataLayer)
31+
}
1932
20-
if (!id) {
21-
throw new Error(
22-
`id configuration parameter is required, try <FacebookPixel id="12345" /> or <FacebookPixel id={['12345', '67890']} /> for multiple pixels`
23-
)
24-
}
33+
function query (cmd, params) {
34+
_fbq(cmd, ...params)
35+
}
2536
26-
pixels = Array.isArray(id) ? id : [ id ]
37+
function callback () {
38+
if (!window.fbq) { return }
2739
28-
/* eslint-disable */
29-
const scr = (f, b, e, v, n, t, s) => {
30-
if (f.fbq) return; n = f.fbq = function (...args) {
31-
n.callMethod ?
32-
n.callMethod.apply(n, args) : n.queue.push(args)
33-
};
34-
if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = version;
35-
n.queue = [];
36-
t = b.createElement(e);
37-
t.async = true;
38-
t.defer = true;
39-
t.src = v;
40-
s = b.getElementsByTagName('body')[0];
41-
s.parentNode.appendChild(t, s);
42-
}
43-
44-
scr(window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js')
45-
/* eslint-enable */
40+
pixels.forEach(pixel => query('init', [pixel]))
4641
47-
_fbq = window['fbq']
48-
49-
if (enabled) {
50-
enable()
51-
}
52-
}
42+
return queue.subscribe(queue => {
43+
let next = queue.length && queue.shift()
5344
54-
function init () {
55-
pixels.forEach(id => {
56-
query('init', id)
57-
})
58-
}
59-
60-
export function track (event = 'PageView', data = undefined, id = undefined) {
61-
if (id) {
62-
if (pixels.includes(id)) {
63-
query('trackSingle', id, event, data)
64-
} else {
65-
console.warn('Attempted to send event to unknown pixel', id)
45+
while (next) {
46+
const { type, params } = next
47+
query(type, params)
48+
next = queue.shift()
6649
}
67-
} else {
68-
query('track', event, data)
69-
}
70-
}
71-
72-
export function query (cmd, ...option) {
73-
_fbq(cmd, ...option)
50+
})
7451
}
7552
</script>

src/functions.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { queue } from './queue.js'
2+
3+
function init (id) {
4+
queue.update(existing => [ ...existing, { type: 'init', params: [ id ] } ])
5+
}
6+
7+
function trackSingle (id, event, data) {
8+
queue.update(existing => [ ...existing, { type: 'trackSingle', params: [ id, event, data ] } ])
9+
}
10+
11+
function trackCustom (event, data) {
12+
queue.update(existing => [ ...existing, { type: 'trackCustom', params: [ event, data ] } ])
13+
}
14+
15+
function track (event, data) {
16+
queue.update(existing => [ ...existing, { type: 'track', params: [ event, data ] } ])
17+
}
18+
19+
export {
20+
init,
21+
trackSingle,
22+
trackCustom,
23+
track
24+
}

src/index.js

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import FacebookPixel from './FacebookPixel.svelte'
2+
import * as fb from './functions.js'
3+
4+
export { FacebookPixel, fb }

src/queue.js

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { writable } from 'svelte/store'
2+
3+
export const queue = writable([])

0 commit comments

Comments
 (0)