vine-tracker v1.3.4
vine-tracker
Tracking framework for Vue.js (and even React).
Installation
npm install vine-tracker
If you need to use this library on production environment, make sure that you have installed any script bundler like Webpack. It is not supported for direct use in browsers since it relies on some CommonJS modules.
Usage
// Import function and channel
import { track } from 'vine-tracker';
import 'vine-tracker/dist/lib/channels/gio';
// Custom configure
track.config.disabled = process.env.NODE_ENV === 'production'
? ['gio'] : false;
track.config.defaultChannels = ['gio'];
// Send event by default channel
track('click', {
id: 'foo',
});
// Or config for specified channel
track('config:user', {
id: uuid(),
}, ['gio']);
// ... and send event by it
track('pageview', {
query: location.search
}, ['gio']);
When an event is sent by track
, the event name and data will be passed to the track
method of the corresponding channel. For events of the form [type]:[key]
, the method corresponding to type
will be called.
Currently there are built-in implementations of console
and gio
channels, which you need to import when using them:
import 'vine-tracker/dist/lib/channels/gio';
The channel could be registered or overwritten by yourself:
import { getChannel, registerChannel } from 'vine-tracker/dist/core/channel';
const APIChannel = getChannel('api');
registerChannel('api', {
...APIChannel,
async track(key, data) {
try {
await axios.post('/my-address', {
event: key,
data: JSON.stringify(data),
});
} catch (err) {
// ignore error
}
},
});
You can also use the built-in Vue plugin:
import { createApp } from 'vue';
import { VueTracker } from 'vine-tracker/dist/vue';
import 'vine-tracker/dist/lib/channels/api';
createApp()
.use(VueTracker, {
// equivalent to assigning to track.config
defaultChannels: ['api'],
});
// in component methods
this.$track('click', {
id: 'foo',
});
For Vue 2.x:
import Vue from 'vue';
import { VueTracker } from 'vine-tracker/dist/vue-v2';
import 'vine-tracker/dist/lib/channels/api';
Vue.use(VueTracker, {
// equivalent to assigning to track.config
defaultChannels: ['api'],
});
Advanced Topics for Vue
If you're using Vue, a directive named track-by
and its corresponding instance method $trackBy
are provided, which support bubbling up.
<template>
<div>
<div v-track-by:appear="{ module: 'card' }"></div>
<div v-track-by:click.route="{ page: 'user' }"></div>
<div @click="handleClick"></div>
</div>
</template>
<script>
export default {
methods: {
handleClick() {
this.$trackBy('click', { id: 'foo' });
// ...
},
},
};
</script>
Options
The method $trackBy
will call the trackedBy
custom lifecycle function on the nearest component (with itself).
export default {
trackedBy(key, data, channels) {
if (key === 'appear') {
data = { scene: 1000, ...data };
}
return this.$trackBy.final(key, data, channels);
// or bubbles
// return this.$parent.$trackBy(key, data, channels);
},
};
You should always return either undefined
or a calling of track
or trackBy
in your trackedBy
functions, or it will cause errors when applying some features.
The trackedBy
can be also declared as an object:
export default {
trackedBy: {
// If the value of 'final' is truthy, the event will be send
// otherwise it will bubble to the parent component
final: true,
// Prevent all received events
prevented: true,
// Reset the **default** channel for all received events
channels: ['api'],
// The object will be merged in event data whatever the key is
with: {
attribute: 1,
},
// And this only if the key is 'appear'
appear: {
scene: 1000,
},
// Visit `this` by declaring a method
route() {
return {
scene: 1001,
module: this.name,
};
},
// 'default' will be used if there is no key matched
default: {
scene: 1002,
},
},
};
Modifiers
The parent component can add more data by .with
modifier.
<template>
<div>
<ChildComponent v-track-by:appear.with="{ page: pagination.page }"></ChildComponent>
</div>
</template>
It will be also added to other tracking actions defined on the current template. If you are using .with
without arg specified, it will be added to every tracking event data.
<template>
<div>
<ChildComponent
v-track-by.with="{ page: pagination.page }"
v-track-by:appear="{ scene: 1000 }"
v-track-by:click.route="{ scene: 1001 }"
></ChildComponent>
</div>
</template>
You can also use .prevent
to prevent tracking events from bubbling up.
<template>
<div>
<ChildComponent v-track-by:appear.prevent></ChildComponent>
</div>
</template>
Collecting
Sometimes, for example, when you want to send a tracking event of route
, you may want to collect data on the previous page and then send it after navigating to a new page. In this case, you can use the $collectBy
method, which only returns the data on the link without actually sending the event:
export default {
methods: {
handleClick() {
const data = this.$collectBy('route');
// ...
},
},
};
In particular, if you specify the global track.config.disabled
with 'true', then $collectBy
will no longer be able to collect data.
Composition APIs
You can also use the following Composition APIs:
<template>
<div>
<div v-track-by:appear="{ module: 'card' }"></div>
<div v-track-by:click.route="{ page: 'user' }"></div>
<div @click="handleClick"></div>
</div>
</template>
<script>
import { defineTrackedBy, useTracker } from 'vine-tracker/dist/vue';
export default {
setup() {
defineTrackedBy({
final: true,
})
const { trackBy, collectBy } = useTracker();
function handleClick() {
trackBy('click', { id: 'foo' });
// ...
}
return {
handleClick,
};
},
};
</script>
Support for React
You can use it in a similar way in React.
In the form of components:
import { Tracker } from 'vine-tracker/dist/react'
function Component() {
const [count, setCount] = useState(0)
const trackedBy = useMemo(() => ({
default: {
count,
},
}), [count])
return (
<div className="component">
<Tracker context={trackedBy}>
<ChildComponent />
</Tracker>
</div>
)
}
import { Tracker } from 'vine-tracker/dist/react'
function ChildComponent() {
return (
<Tracker by="click" data={{ foo: 'bar' }}>
<button />
</Tracker>
)
}
In the form of props injections:
import { withTracker } from 'vine-tracker/dist/react'
function Component(props) {
const handleClick = useCallback(() => {
props.trackBy('click')
})
return (
<button onClick={handleClick} />
)
}
export default withTracker(Component)
In the form of Hooks:
import { useTracker } from 'vine-tracker/dist/react'
function Component(props) {
const { trackBy } = useTracker()
const handleClick = useCallback(() => {
trackBy('click')
})
return (
<button onClick={handleClick} />
)
}
Configuration
The following configurations are currently supported:
disabled
: When set totrue
, all tracking behaviors will be disabled.- You can also set an array of strings to disable some specific channels.
debug
: When set totrue
, all tracking behaviors will be printed in the console.- Although this behavior is implemented based on the console channel, it does not affect any logic related to channels, such as the return value of the
track
function.
- Although this behavior is implemented based on the console channel, it does not affect any logic related to channels, such as the return value of the
errorHandler
: Function used to handle errors when the channels' behaviors generate an error. Defaults toconsole.error
.defaultChannels
: Specifies the default channels.keySep
: Specifies the separator between the event type and the event name. Defaults to:
.
The built-in channels provide the following configuration:
gioInstance
: The GrowingIO instance that thegio
channel uses to send tracking data. Defaults towindow.gio
.
When working with Vue, the following configurations are also supported:
fallbackTrackingBy
: When set totrue
, tracking data will eventually be sent even if no component declares thefinal
option. Defaults tofalse
.appearingInterval
: The time interval used to handleappear
events. Defaults to300
.appearingOptions
: Options for theIntersectionObserver
used to handle theappear
event.