Next.js如何接入百度统计

发布时间:2020-12-27 13:05:26阅读:(1492)

Next.js是一个非常优秀的React服务端渲染解决方案。一般做服务端渲染,大多数因素都是为了SEO,既然做了SEO,那么肯定会嵌入一些网站统计代码,本文将介绍如何在Next.js内使用百度统计代码。

一、获取百度统计代码

这一步就不多介绍了,详细大部分人都知道。

二、嵌入统计代码

next.js并没有像其他react框架一样有一个index.html入口,那么统计代码该放在哪个地方呢?next.js官方提供了这两个入口可以放置一些全局的代码:自定义Document或者自定义App。

官方文档如下:

虽然这两个地方都可以放置,但我还是喜欢放在App内,_app.js代码如下:

import React from 'react';
import { Head } from 'next/document';

function MyApp({ Component, pageProps }) {

const getAnalyticsTag = () => {
return {
__html: `
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?你的代码";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();`,
}
}

return (
<>
<Head>
<script dangerouslySetInnerHTML={getAnalyticsTag()}/>
</Head>
<Component {...pageProps} />
</>
)
}

export default MyApp;

然后我们回到浏览器,访问页面,看到会有一个hm.gif的请求,就说明代码集成没问题了。

那么到这里就结束了吗?显然没有。我们发现第一次进入页面的时候确实有hm.gif这个请求,但是在页面切换的时候,并没有这个请求。说明页面的切换并没有被统计进去,那是为什么呢?

因为Next.js路由采用的是前端路由,所以整个应用出来第一次是服务端渲染出来的,后面的都是在客户端渲染的,本质上还是一个单页面应用,而百度统计代码并没有很好的适配单页面应用,所以我们需要自己处理这部分逻辑。

三、解决路由切换时统计并不生效问题

Next Router设计了这个几个事件:

https://nextjs.org/docs/api-reference/next/router#routerevents

这里我们主要使用routeChangeComplete这个事件,这个事件会在路由切换完成后触发,因此我们在这里加上手动埋点。代码依旧在_app.js

import { Router } from 'next/router';
Router.events.on('routeChangeComplete', (url) => {
try{
window._hmt.push(['_trackPageview', url]);
}catch (e){}
})

再回到浏览器中,就能看到页面切换时也有hm.gif这个请求了。

至此,百度统计的代码就加完了。

标签:seonext.js

发表评论

评论列表(有5条评论1492人围观)
jackiexiao2023-09-07 19:39:27

遇到一个错误不知道怎么解决

window._hmt.push(['_trackPageview', url]);

# Property '_hmt' does not exist on type 'Window & typeof globalThis'

另外,我必须放在_document 里头, 在_app 里头使用 <head> 会报错

凌杰2023-09-07 20:23:04

window对象在服务端渲染的时候是不存在的,你在使用window之前可以先判断下window是否存在,存在再调用

jackiexiao2023-09-07 20:42:20

完整代码如下,我 用 // @ts-ignore 忽略了 Property '_hmt' does not exist on type 'Window 的问题,我猜是 typescript 不知道函数中创建了 _hmt 对象导致的


import { Html, Head, Main, NextScript } from 'next/document';
import { Router } from 'next/router';
import { useEffect } from 'react';

export default function Document() {
useEffect(() => {
Router.events.on('routeChangeComplete', (url) => {
try {
// @ts-ignore
window._hmt.push(['_trackPageview', url]);
} catch (e) {}
});
}, []);
const getAnalyticsTag = () => {
return {
__html: `
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?94feacca3c0d1e2d9158a7bfcfacfa5a";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();`,
};
};
return (
<Html lang='en'>
<Head>
<script dangerouslySetInnerHTML={getAnalyticsTag()} />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}

凌杰2023-09-07 21:02:24

哦,看错问题了。确实是类型定义引起的。

解决方案1:在next-env.d.ts中重新定义window类型,把_html加进去,可以参考:https://blog.csdn.net/weixin_40548203/article/details/120767696

解决方案2:直接将window转为any, 如:(window as any)._html.xxx

jackiexiao2023-09-07 21:31:09

thx!