安装依赖
// npm 安装
npm install @datapunt/matomo-tracker-react
// pnpm 安装
pnpm install @datapunt/matomo-tracker-react
文档:https://developer.matomo.org/guides/integrate-introduction
一、注册和收集代码异常错误信息
src/index.js文件
- 引入 MatomoProvider,createInstance
import { MatomoProvider, createInstance } from '@datapunt/matomo-tracker-react'
- 注册站点信息
const instance = createInstance({
urlBase: 'https://xxx.xxx/matomo', // 主机域名
siteId: 3, // 站点id
userId: localStorage.getItem("userId"), // 选填,默认用手机号
heartBeat: { // optional, enabled by default
active: true, // optional, default value: true
seconds: 10 // optional, default value: `15
},
linkTracking: false, // optional, default value: true
configurations: { // optional, default value: {}
// any valid matomo configuration, all below are optional
disableCookies: true,
setSecureCookie: true,
setRequestMethod: 'POST'
}
})
- 在src目录下新建文件errorCollect.jsx(ErrorBoundary错误收集)
import React, {useImperativeHandle,forwardRef} from "react";
import { useMatomo } from "@datapunt/matomo-tracker-react";
function ErrorCollect (_props,ref) {
const { trackEvent } = useMatomo();
useImperativeHandle(ref, () => ({
onError: (error) => {
trackEvent({
category: "ErrorBoundary",
action: error?.stack,
});
}
}));
return (
<></>
);
}
export default forwardRef(ErrorCollect);
- 改造index.js下的 ReactDOM.render部分代码
注意:先引入 ErrorCollect 组件: import ErrorCollect from “./errorCollect”;
function App() {
const onErrorRef = useRef();
function onError (error) {
onErrorRef.current.onError(error);
}
return (
<>
<ErrorBoundary FallbackComponent={ErrorFallback} onError={onError}>
<AppProvider>
<AliveScope>
<ThemeProvider
theme={{
btnBgImage: "linear-gradient(137deg, #ff5b5b 0%, #db0113 100%)"
}}
>
<MatomoProvider value={instance}>
<Routes />
</MatomoProvider>
</ThemeProvider>
</AliveScope>
{/* 仅在非生产环境展示动态切换环境组件 */}{" "}
{env !== "RELEASE" ? <DynamicApi /> : null}
</AppProvider>
</ErrorBoundary>
<MatomoProvider value={instance}>
<ErrorCollect ref={onErrorRef}></ErrorCollect>
</MatomoProvider>
</>
);
}
ReactDOM.render(
<App />,
document.getElementById("root")
);
二、全局处理代码跟踪
src/routes/index.js文件
- 引入 useMatomo
import { useMatomo } from "@datapunt/matomo-tracker-react";
- 使用 useMatomo
const { trackPageView, pushInstruction } = useMatomo()
- 使用 trackPageView
const triggerMatomo = () =>{
pushInstruction("setUserId", "xxx"); // 此为举例,可再此添加更多的内容收集
pushInstruction('setDocumentTitle', '测试')
// 最后执行
trackPageView()
}
三、接口请求异常信息收集
- 改造请求方法
src/services/index.js
- 重写localStorage的setItem
const rewriteLocalStorageSetItem = (data) => {
var orignalSetItem = localStorage.setItem;
localStorage.setItem = function (key, newValue) {
var setItemEvent = new Event("setItemEvent");
setItemEvent.newValue = newValue;
window.dispatchEvent(setItemEvent);
orignalSetItem.apply(this,arguments);
};
localStorage.setItem("JS_API_ERROR", JSON.stringify(data));
};
- 在请求失败响应代码中加上如下代码
rewriteLocalStorageSetItem(res) // res为接口响应返回的错误信息,最好拼接上userId和transCode
- 改造错误收集组件
src/errorCollect.jsx
- 创建事件监听器,监听 setItemEvent 自定义事件
function getApiError (e) {
if (e.newValue) {
setErrorRes(e.newValue);
}
};
useEffect(() => {
window.addEventListener("setItemEvent", getApiError);
// dom节点销毁时移除事件监听器
return () => {
window.removeEventListener("setItemEvent", getApiError);
};
}, []);
- 触发matomo事件
useEffect(() => {
const api_error = localStorage.getItem("JS_API_ERROR");
if (errorRes && errorRes == api_error) {
trackEvent({
category: "ApiError",
action: errorRes,
});
}
}, [errorRes]);
完整代码如下
import React, {useImperativeHandle,forwardRef, useEffect, useState} from "react";
import { useMatomo } from "@datapunt/matomo-tracker-react";
function ErrorCollect (_props,ref) {
const { trackEvent } = useMatomo();
const [errorRes, setErrorRes] = useState();
// 将事件 onError 暴露给父组件
useImperativeHandle(ref, () => ({
onError: (error) => {
trackEvent({
category: "ErrorBoundary",
action: error?.stack,
});
}
}));
function getApiError (e) {
if (e.newValue) {
setErrorRes(e.newValue);
}
};
useEffect(() => {
window.addEventListener("setItemEvent", getApiError);
// dom节点销毁时移除事件监听器
return () => {
window.removeEventListener("setItemEvent", getApiError);
};
}, []);
useEffect(() => {
const api_error = localStorage.getItem("JS_API_ERROR");
if (errorRes && errorRes == api_error) {
trackEvent({
category: "ApiError",
action: errorRes,
});
}
}, [errorRes]);
return (
<></>
);
}
export default forwardRef(ErrorCollect);
四、收集信息API
注意:
- 部分信息注册时已添加,如userId,siteId, trackerUrl等,具体看上面注册站点信息
- 为埋点收集做好区分页面标题数据,不同页面需添加对应的标题(页面开发时加上)
- 防止matomo将同一路由但不同参数的页面归纳成不同页面进行收集,需进行下面第6项操作
- 设置页面标题
pushInstruction('setDocumentTitle', document.title)
- 设置userId
pushInstruction("setUserId", "test_userid_xxx");
- 重置userId(如退出登录后)
pushInstruction("resetUserId");
- 设置站点id
pushInstruction("setSiteId", 3);
- 设置跟踪域名
const u = 'https://xxx.com.cn/matomo/'
pushInstruction("setTrackerUrl", u+'matomo.php');
- 重置页面url
pushInstruction("setCustomUrl", 'xxx');
- 创建跟踪Cookie
pushInstruction('setCookiePath', '/user/MyUsername');
- 跟踪同一网站中的一个域及其子域
pushInstruction('setCookieDomain', '*.example.com');
pushInstruction('setDomains', '*.example.com');
- 是否跟踪初始页面
pushInstruction("enableLinkTracking");
- 异步调用跟踪
pushInstruction('API_method_name', parameter_list );
- 强制Matomo创建新访问
pushInstruction('appendToTrackingUrl', 'new_visit=1');
trackPageView()
pushInstruction('appendToTrackingUrl', '');
- 跟踪页面中的所有内容
pushInstruction("trackAllContentImpressions");
注意:
trackAllContentImpressions api 有两个属性(皆非必填)
1、checkOnScroll:每次滚动后是否重新扫描DOM
2、timeIntervalInMs:每隔X毫秒重新扫描整个DOM,默认750,若要禁用,直接设置为 0
pushInstruction("trackAllContentImpressions", true, 500);
- 跟踪页面中部分内容
const myEl = document.getElementById('xxx')
pushInstruction("trackContentImpressionsWithinNode", myEl);
- 半自动跟踪交互
pushInstruction('trackContentImpression', 'Content Name', 'Content Piece', 'https://www.example.com');
div.addEventListener('click', function () {
pushInstruction('trackContentInteraction', 'tabActivated', 'Content Name', 'Content Piece', 'https://www.example.com');
});
注:对这些方法的每次调用都会向您的Matomo跟踪器实例发送一个请求。多次执行此操作可能会导致性能问题。
- 手动触发目标转换
// 记录目标1的转换
pushInstruction('trackGoal', 1);
// 使用自定义收入集记录目标1的转换
pushInstruction('trackGoal', 1, <?php echo $cart->getCartValue(); ?>]);
- 准确测量每页花费的时间
// 准确测量访问时间
pushInstruction('enableHeartBeatTimer');
// 准确测量在访问中花费的时间更改选项卡需要活动多长时间才能算作查看时间(以秒为单位)
// 要求页面活动查看30秒才能发送任何心跳请求
pushInstruction('enableHeartBeatTimer', 30);
- 内部搜索跟踪
pushInstruction('trackSiteSearch',
// 搜索关键字
"Banana",
// 在搜索引擎中选择的搜索类别。如果不需要,设置为false
"Organic Food",
// “搜索结果”页面上的结果数。零表示“无结果搜索关键字”。如果您不知道,则设置为false
0
);
- 添加自定义变量
pushInstruction('setCustomVariable',
// 索引,存储此自定义变量名的从1到5的数字
1,
// Name,变量的名称,例如:Gender、VisitorType
"Gender",
// Value, 例如: "Male", "Female" or "new", "engaged", "customer"
"Male",
// 自定义变量的范围,“visit”表示自定义变量适用于当前"visit"
"visit"
);
- 删除自定义变量
pushInstruction('deleteCustomVariable', 1, "visit") // 删除为当前索引为1中的变量
- 检索自定义变量
pushInstruction( function() {
var customVariable = this.getCustomVariable( 1, "visit" );
// 返回自定义变量: [ "gender", "male" ]
// 使用customVariable执行某些操作...
})
- 跨跟踪请求跟踪自定义维度
pushInstruction('setCustomDimension', customDimensionId = 1, customDimensionValue = 'Member');
- 通过CSS或JavaScript将点击作为outlink进行跟踪
<a href='https://mysite.com/partner/' class='external'>Link I want to track as an outlink</a>
// 所有点击css类“external”的链接都将被计算为outlink
// 还可以传递字符串数组
pushInstruction('setLinkClasses', "external");
- 设置跟踪文件下载
pushInstruction('setDownloadExtensions', "jpg|png|gif");
// 默认情况下,在Matomo界面中,任何以以下扩展名之一结尾的文件都将被视为“下载”:
7z|aac|arc|arj|apk|asf|asx|avi|bin|bz|bz2|csv|deb|dmg|doc|
exe|flv|gif|gz|gzip|hqx|jar|jpg|jpeg|js|mp2|mp3|mp4|mpg|
mpeg|mov|movie|msi|msp|odb|odf|odg|odp|ods|odt|ogg|ogv|
pdf|phps|png|ppt|qt|qtm|ra|ram|rar|rpm|sea|sit|tar|
tbz|tbz2|tgz|torrent|txt|wav|wma|wmv|wpd||xls|xml|z|zip
- 添加跟踪文件下载
pushInstruction('addDownloadExtensions', "mp5|mp6");
- 移除跟踪文件下载
pushInstruction('removeDownloadExtensions', "png|mp4");
- 将点击记录为下载
// 所有点击css类“download”的链接都将被视为下载
pushInstruction('setDownloadClasses', "download");
- 更改暂停计时器
pushInstruction('setLinkTrackingTimer', 250);
- 禁用下载和异常链接跟踪
// 默认情况下,Matomo跟踪代码启用点击和下载跟踪。要禁用所有自动下载和outlink跟踪,必须删除对enableLinkTracking()函数的调用:
// 即注释掉下面此行即可
// pushInstruction("enableLinkTracking");
- 为特定CSS类禁用
pushInstruction('setIgnoreClasses', "no-tracking");
- 为特定链接禁用
// 如果您想忽略特定链接上的下载或outlink跟踪,可以向其中添加 matomo_ignore 或 piwik_ignore css类
<a href='https://builds.matomo.org/latest.zip' class='matomo_ignore'>File I don't want to track as a download</a>
- 选择用户退出
pushInstruction('optUserOut');
- 选择用户加入
var u="xxxx";
// 新站点 ID = 7
var websiteIdDuplicate = 7;
pushInstruction('addTracker', u+'matomo.php', websiteIdDuplicate);