如何在 RemixJS 中跟踪页面浏览量?
我正在构建一个 Remix 应用程序,并希望根据用户正在查看的页面在我的数据库中记录一些用户分析。我还想逐个路由地执行此操作,而不仅仅是简单地使用原始 URL。
例如:我想知道“用户查看的 URL /emails/123”以及“用户查看的路线 /emails/$emailId”
这个问题可以概括为“我想为每个用户导航运行一段服务器代码”
对于我的跟踪,我假设用户在其浏览器中启用了 JavaScript。
我尝试过的解决方案:
在加载器中记录
这将类似于:
export const loader: LoaderFunction = async ({ request, params }): Promise<LoaderData> => {
myDb.recordPageVisit(request.url);
}
这不起作用,因为每次访问页面时可以多次调用加载器(例如,运行操作后)
请求参数中可能隐藏了一些值它告诉我们这是初始页面加载还是稍后访问,但如果是这样,我找不到它,包括当我检查原始 HTTP 请求时。
必须将此代码放入每个加载器中也很烦人。
在节点代码中记录 URL
我正在使用 @remix-run/node 作为我的基础混音服务器,因此我有设置节点中间件的逃生舱口,我认为这可能是一个很好的答案:
const app = express();
app.use((req, res, next) => {
if (req.url.indexOf("_data") == -1) {
myDb.recordPageVisit(req.url);
}
next();
});
我尝试忽略路由其中的 _data
,但这不起作用,因为 remix 非常高效,并且当用户导航时,它使用 ajax-y 调用仅获取 loaderData,而不是从服务器。我知道这是 Remix 的行为,但在走这条路之前我不记得它了 :facepalm:
据我所知,无状态地跟踪唯一的页面浏览量是不可能的(即纯粹基于当前的 URL) - 你还需要查看用户的上一页。
我想知道引用者是否允许它无状态地工作,但引用者似乎没有按照我希望的方式运行:在第一个加载器请求页面数据时,引用者标头已经设置为当前页面。因此,基于引用者,初始加载和突变后加载看起来是相同的。我不知道这在技术上是否是一个错误,但这肯定不是我期望的行为。
I am building a Remix app, and wanted to record some user analytics in my database based on what page the user was viewing. I also wanted to do so on a route by route basis, rather than just simply the raw URL.
For example: I wanted to know "user viewed URL /emails/123" as well as "user viewed route /emails/$emailId"
This problem could be generalized as "I want to run a piece of server code once per user navigation"
For my tracking I'm assuming users have javascript enabled in their browser.
Solutions I tried:
Record in the loader
This would be something like:
export const loader: LoaderFunction = async ({ request, params }): Promise<LoaderData> => {
myDb.recordPageVisit(request.url);
}
This doesn't work because the loader can be called multiple times per page visit (eg. after an action is run)
It's possible that there's some value hidden in the request parameter that tells us whether this is an initial page load or if it's a later visit, but if so I couldn't find it, including when I examined the raw HTTP requests.
It's also annoying to have to put this code inside of every loader.
Record the URL in the node code
I'm using @remix-run/node as my base remix server, so I have the escape hatch of setting up node middleware, and I thought that might be a good answer:
const app = express();
app.use((req, res, next) => {
if (req.url.indexOf("_data") == -1) {
myDb.recordPageVisit(req.url);
}
next();
});
I tried ignoring routes with _data
in them, but that didn't work because remix is being efficient and when the user navigates, it is using an ajax-y call to only get the loaderData rather than getting the full rendered page from the server. I know this is the behavior of Remix, but I had not remembered it before I went down this path :facepalm:
As far as I can tell it's impossible to stateless-ly track unique pageviews (ie based purely on the current URL) - you need see the user's previous page as well.
I wondered if referer would allow this to work statelessly, but it appears that the referer is not behaving how I'd hoped: the referer header is already set to the current page in the first loader request for the data for the page. So initial load and load-after-mutation appear identical based on referer. I don't know if this is technically a bug, but it's certainly not the behavior I'd expect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最终通过在客户端中进行浏览量跟踪来解决此问题。为了支持在数据库中记录这一点,我实施了一条路线,该路线在位置更改时刚刚收到帖子。
React-Router的USEATICE的文档实际上包括此确切的情况为示例。
来自 https://reactrouter.com/docs/docs/en/en/v6/api#uselocation :
但是,这在混音中不太奏效 - 操作后的位置值(相同的文本值,但可能不同的参考值)更改。因此,我开始保存所看到的最后一个位置字符串,然后仅在更改位置字符串值时报告一个新的页面浏览量。
因此,在添加了对当前位置的状态跟踪后,我登陆了:
匹配代码对于仅跟踪原始URL并不是必需与该值的密切匹配 - 我剥离“路由/”服务器。匹配文档: htttps://remix.run/docs/docs/docs/en/en/en/en/v1/api/ remix#usematches
客户端页面浏览量跟踪有点烦人,因为客户端是片状的,但是对于当前的混音行为,我相信这是唯一的真正选择。
I ended up solving this by doing the pageview tracking in the client. To support recording this in the DB, I implemented a route that just received the POSTs when the location changed.
The documentation for react-router's useLocation actually includes this exact scenario as an example.
From https://reactrouter.com/docs/en/v6/api#uselocation:
However, that doesn't quite work in remix - the location value is changed after actions (same text value, but presumably different ref value). So I started saving the last location string seen, and then only report a new pageview when the location string value has changed.
So after adding that stateful tracking of the current location, I landed on:
The matches code is not necessary for tracking just raw URLs, but I wanted to extract the route form (eg /emails/$emailId), and matches.id is a close match to that value - I strip "routes/" serverside. Matches docs: https://remix.run/docs/en/v1/api/remix#usematches
Client side pageview tracking is a bit annoying since clients are flaky, but for the current remix behavior I believe this is the only real option.
路线是否有不同的方式,混音很有趣,因为整个父路线的事情
*
所以我使用路线记录器Beans.io
https://www.npmjs.com/package/豆类
Did it a different way for routes, remix is funny cuz of the whole parent route thing
*
so I use a route loggerBeans.io
https://www.npmjs.com/package/beansio