为vitepress静态网站增加访问统计代码

最近写自研的一个软件产品文档,首次使用了vitepress。看着官方文档,磕磕绊绊的算是完成了一版。比如:

在为文档网站添加访问统计代码时,遇到了些困难。网上搜索和掘金都没有合适的答案。这里介绍我的具体实现,以供需要的同学使用。

一、vitepress的相关配置

为vitepress静态网站增加统计代码,需要在2个地方进行配置:head 和 路由。

1.1 head 配置

我们要增加网站访问统计代码。无论你用的是google还是百度,或者其他第三方统计服务,都需要在head中进行配置。

在 .vitepress/config.ts 文件中,配置如下:

js 复制代码
 head: [
    // ... 其他部分的配置,比如
    
    [
      'script',
      {},
      `
      window._hmt = window._hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?abcdefgeggsdfsdf123123";
        var s = document.getElementsByTagName("script")[0]; 
        s.parentNode.insertBefore(hm, s);
      })();
      `,
    ],
  ],

由于google无法访问,又不想花银子,所以这里以某度统计的免费版为例。这里代码中和某度统计官方文档不同的地方,在与第 8 行。(不清楚如何将第8行高亮显示,请知道的同学留言告诉我 :))

window._hmt = window._hmt || [];

官网文档中的实例是:var _hmt = _hmt || [];

之所以要写入全局变量window中,是为了下面介绍的第2项配置。在第二项配置中,会读取这个 _hmt 变量。如果不存入 window 对象中,则读取不到。

1.2 路由配置

vitepress是基于文件路径的路由,并且构建生成的都是静态的html页面。根据vitepress的官网介绍,vitepress构建的实质上是一个单页面应用(SPA)。

而用户在这个SPA应用中,会访问不同的静态页面。我们必须把他所有不同的访问url都进行统计记录下来。

在SPA应用中,那么仅仅在head部分增加一个js函数来发送访问统计数据到统计平台,就显得不够了。因为这个js函数在spa中,只会执行一次。

既然是spa,那么页面的跳转,就离不开router,我们只需要跟踪路由的变化即可。

1.2.1 主题配置项

我们先来看看主题的主要配置项:

ts 复制代码
interface EnhanceAppContext {
    app: App;
    router: Router;
    siteData: Ref<SiteData>;
}

interface Theme {
    Layout?: Component;
    enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>;
    extends?: Theme;
    /**
     * @deprecated can be replaced by wrapping layout component
     */
    setup?: () => void;
    /**
     * @deprecated Render not found page by checking `useData().page.value.isNotFound` in Layout instead.
     */
    NotFound?: Component;
}

其中:enhanceApp是一个参数为EnhanceAppContext的函数。而EnhanceAppContext的一个属性是Router类型。我们再来看看这个Router:

ts 复制代码
interface Router {
    /**
     * Current route.
     */
    route: Route;
    /**
     * Navigate to a new URL.
     */
    go: (to?: string) => Promise<void>;
    /**
     * Called before the route changes. Return `false` to cancel the navigation.
     */
    onBeforeRouteChange?: (to: string) => Awaitable<void | boolean>;
    /**
     * Called before the page component is loaded (after the history state is
     * updated). Return `false` to cancel the navigation.
     */
    onBeforePageLoad?: (to: string) => Awaitable<void | boolean>;
    /**
     * Called after the route changes.
     */
    onAfterRouteChanged?: (to: string) => Awaitable<void>;
}

从上面的几个接口定义可以看出,EnhanceAppContext的router属性,实际上是vue-router实例的一个代理包装。它有一个当前路由的对象、go方法(跳转方法)和3个事件。根据3个事件的命名,我们可以发现onBeforeRouteChange事件,就是我们需要的方法。即:在路由改变之前进行处理。

1.2.2 自定义路由改变事件

我原来的主题配置文件 ( .vitepress/theme/index.js ) 是这样的:

ts 复制代码
import './tailwind.postcss';
import DefaultTheme from 'vitepress/theme';
export default { ...DefaultTheme };

我的目的很明确,主要是写文档。vitepress的默认主题我觉着已经够用了。由于对默认的主题样式不熟悉,同时为了增加一些外部的样式以简化文档页面一些自定义的样式,我引入了 tailwind.css,但是主题文件很简单。只导出了默认的主题。

现在对这个文件内容,做出如下改变:

ts 复制代码
import './tailwind.postcss';
import DefaultTheme from 'vitepress/theme';

DefaultTheme.enhanceApp = ({ app, router, siteData }) => {
  router.onBeforeRouteChange = (to) => {
    console.log('路由将改变为: ', to);
    if (typeof _hmt !== 'undefined') {
      _hmt.push(['_trackPageview', to]);
    }
  };
};
export default { ...DefaultTheme };

默认主题对象,是不具有enhanceApp属性的(上面的接口定义,该属性是可选的),因此我们手动定义他的内容即可。

在这改代码中 _hmt 就是上面文档介绍的,存入 window 对象的那个对象,如果不存入window,则在build文档时,会发生错误。其 push 方法,就是向某度统计发送当前路径的数据。

当然,这里的 onBeforeRouteChange 事件实现是向某度统计发送url路径。你可以根据实际的统计平台的接口要求,自己实现这一块的逻辑。原理是一样的。

实际运行情况如下:

可以看到,每一次的路由变化,控制台都输出了要跳转的url。都会发送一个 hm.baidu.com/hm.gif?cc=1... 的远程请求。这个请求地址,正是目标统计平台接收数据的地址。

至此,我们实现了为vitepress静态网站增加访问统计代码的功能目标。

相关推荐
smileNicky7 分钟前
在 VSCode 中运行 Vue.js 项目
ide·vue.js·vscode
小马哥编程1 小时前
React和Vue在前端开发中, 通常选择哪一个
前端·vue.js·react.js
HCl+NaOH=NaCl+H_2O2 小时前
Quasar组件 Carousel走马灯
javascript·vue.js·ecmascript
Varpb5 小时前
【vue】【环境配置】项目无法npm run serve,显示node版本过低
前端·vue.js·npm
Minyy115 小时前
Vue3指令(二)--v-text、v-html数据渲染,计算属性
前端·javascript·vue.js·前端框架·vue·html
工业互联网专业7 小时前
基于springboot+vue的机场乘客服务系统
java·vue.js·spring boot·毕业设计·源码·课程设计·机场乘客服务系统
inksci7 小时前
Vue 3 打开 el-dialog 时使 el-input 获取焦点
前端·javascript·vue.js
绝美焦栖10 小时前
vue复杂数据类型多层嵌套的监听
前端·javascript·vue.js
GoodStudyAndDayDayUp10 小时前
gitlab+portainer 实现Ruoyi Vue后端CI/CD
vue.js·ci/cd·gitlab
.生产的驴11 小时前
Vue3 加快页面加载速度 使用CDN外部库的加载 提升页面打开速度 服务器分发
运维·服务器·前端·vue.js·分布式·前端框架·vue