如何在打开自动静态优化的情况下访问Next.js中的规范URL



我正在开发SEO组件,它需要一个规范的URL。

打开"自动静态优化"后,如何在Next.js中获取静态页面的URL?

使用next/router中的useRouter,可以获得当前页面的pathname,并在<Head/>标记中使用,如下所示:

import { useRouter } from "next/router";
const site = "https://gourav.io";
const canonicalURL = site + useRouter().pathname;
<Head>
<link rel="canonical" href={canonicalURL} />
</Head>

基于fzembow对useRouter().asPath的评论和GorvGoyl的回答,这里有一个实现,它能够处理动态路由,并排除锚点和查询参数URL扩展:

import { useRouter } from "next/router";
const CANONICAL_DOMAIN = 'https://yoursite.com';
const router = useRouter();
const _pathSliceLength = Math.min.apply(Math, [
router.asPath.indexOf('?') > 0 ? router.asPath.indexOf('?') : router.asPath.length,
router.asPath.indexOf('#') > 0 ? router.asPath.indexOf('#') : router.asPath.length
]);
const canonicalURL= CANONICAL_DOMAIN + router.asPath.substring(0, _pathSliceLength);
<Head>
<link rel="canonical" href={ canonicalURL } />
</Head>

使用名为next absolute url的包。它在getServerSideProps中工作。由于getStaticProps在构建时运行,因此没有可用的数据。可以用作

export const getServerSideProps: GetServerSideProps = async (ctx) => {
const { req, query } = ctx;
const { origin } = absoluteUrl(req);      
return {
props: {
canonicalUrl: `${origin}/user-listings`,
},
};
};
export const getStaticProps:GetStaticProps = async (ctx) => {
return {
props: {
canonicalUrl: 'https://www.test.com',
},
};
};

一个超级丑陋的,然而,我发现的最合适的解决方案:

const canonicalUrl = typeof window === 'undefined' ?
'' :
`${window.location.origin}/${window.location.pathname}`;

我的解决方案是在router.asPath.中使用新的URL

const CURRENT_URL = process.env.NEXT_PUBLIC_CURRENT_SITE_URL
const getCanonical = (path: string) => {
const fullURL = new URL(path, CURRENT_URL)
return`${fullURL.origin}${fullURL.pathname}
}
export const Page = () => {
const router = useRouter()
const canonical = getCanonical(router.asPath)
<Head>
<link rel="canonical" href={canonical} />
</Head>
<div>
...
<div>
}

我为_app.js添加了一个规范链接标记,以便它出现在每一页上:

<link
rel="canonical"
href={typeof window !== 'undefined' && `${window.location.origin}${useRouter().asPath}`}
key="canonical"
/>

最新更新