Next.js - 如何确保在触发历史更改事件时设置 <title>?
Next.js - How to make sure <title> is set by the time the history change event fires?
在我的 Next.js 应用中,我使用推荐的方法为各个页面设置 <title>
标签:
import Head from 'next/head'
export default () => <>
<Head><title>My page title</title></Head>
</>
问题是:当触发历史记录更改事件时,document.title
的值并不总是与当前的 URL.
匹配
你可以自己测试一下:
Router.events.on("routeChangeComplete", () => {
if ('browser' in process) {
console.log('--------');
console.log(window.location.href);
console.log(document.title);
}
});
在页面之间导航,您应该观察到 URL 和标题经常不匹配。 URL的值总是对的,而title的值却到处都是。它可以有:
- 正确的值
- 它在上一页的价值
- 完全没有价值
这是使用分析时的一个问题,特别是 GTM - Google 标签管理器,它使用当前 URL 和页面标题来唯一标识访问过的页面。
我在使用 Next.js 7 时遇到过这个问题,升级到 8 后仍未解决。
你知道有什么方法可以解决这个问题吗?也许将历史更改事件延迟到 /pages/
下的组件首次呈现?
谢谢!
这是一个小技巧。 setTimeout(()=>{console.log(document.title)}, 0)
我通过拦截发送到 window.dataLayer.push
的事件并添加一秒延迟以防事件是 gtm.historyChange
.
找到了解决方法
这是我要添加到 _document.js
下的 <Head>
的 GtagScript
组件:
export const GtagScript = () => {
function intercept() {
const scriptTag = document.querySelector('#gtm-js');
if (scriptTag !== null)
scriptTag.addEventListener('load', () => {
window.dataLayer.pushOrig = window.dataLayer.push;
window.dataLayer.push = (e) => {
if (e.event === 'gtm.historyChange') {
setTimeout(function () {
window.dataLayer.pushOrig(e);
console.log(`URL: ${window.location.href} Title: ${document.title}`);
}, 1000);
} else {
window.dataLayer.pushOrig(e);
}
};
});
}
return <>
<script
id="gtm-js"
async
src={`https://www.googletagmanager.com/gtm.js?id=${GA_TRACKING_ID}`}
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}');
${intercept.toString()}
intercept();`
}}
/>
</>
};
我会稍等片刻,看看 ZEIT 团队是否会提供官方修复程序。我的解决方案实际上并没有回答这个问题。它不会设置 <title>
,它只是推迟事件,这不是最佳选择。
您可以使用 setInterval
const firstPageViewEvent = setInterval(() => {
if (document.title) {
// send pageview event
clearInterval(firstPageViewEvent);
}
}, 200);
在我的 Next.js 应用中,我使用推荐的方法为各个页面设置 <title>
标签:
import Head from 'next/head'
export default () => <>
<Head><title>My page title</title></Head>
</>
问题是:当触发历史记录更改事件时,document.title
的值并不总是与当前的 URL.
你可以自己测试一下:
Router.events.on("routeChangeComplete", () => {
if ('browser' in process) {
console.log('--------');
console.log(window.location.href);
console.log(document.title);
}
});
在页面之间导航,您应该观察到 URL 和标题经常不匹配。 URL的值总是对的,而title的值却到处都是。它可以有:
- 正确的值
- 它在上一页的价值
- 完全没有价值
这是使用分析时的一个问题,特别是 GTM - Google 标签管理器,它使用当前 URL 和页面标题来唯一标识访问过的页面。
我在使用 Next.js 7 时遇到过这个问题,升级到 8 后仍未解决。
你知道有什么方法可以解决这个问题吗?也许将历史更改事件延迟到 /pages/
下的组件首次呈现?
谢谢!
这是一个小技巧。 setTimeout(()=>{console.log(document.title)}, 0)
我通过拦截发送到 window.dataLayer.push
的事件并添加一秒延迟以防事件是 gtm.historyChange
.
这是我要添加到 _document.js
下的 <Head>
的 GtagScript
组件:
export const GtagScript = () => {
function intercept() {
const scriptTag = document.querySelector('#gtm-js');
if (scriptTag !== null)
scriptTag.addEventListener('load', () => {
window.dataLayer.pushOrig = window.dataLayer.push;
window.dataLayer.push = (e) => {
if (e.event === 'gtm.historyChange') {
setTimeout(function () {
window.dataLayer.pushOrig(e);
console.log(`URL: ${window.location.href} Title: ${document.title}`);
}, 1000);
} else {
window.dataLayer.pushOrig(e);
}
};
});
}
return <>
<script
id="gtm-js"
async
src={`https://www.googletagmanager.com/gtm.js?id=${GA_TRACKING_ID}`}
/>
<script
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${GA_TRACKING_ID}');
${intercept.toString()}
intercept();`
}}
/>
</>
};
我会稍等片刻,看看 ZEIT 团队是否会提供官方修复程序。我的解决方案实际上并没有回答这个问题。它不会设置 <title>
,它只是推迟事件,这不是最佳选择。
您可以使用 setInterval
const firstPageViewEvent = setInterval(() => {
if (document.title) {
// send pageview event
clearInterval(firstPageViewEvent);
}
}, 200);