我正在开发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"
/>