Skip to content

Commit ff6c51a

Browse files
authored
feat($core): add canonical link to frontmatter (#2658)
1 parent 931e7d9 commit ff6c51a

File tree

4 files changed

+47
-0
lines changed

4 files changed

+47
-0
lines changed

packages/@vuepress/core/lib/client/index.ssr.html

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
<meta name="generator" content="VuePress {{ version }}">
88
{{{ userHeadTags }}}
99
{{{ pageMeta }}}
10+
{{{ canonicalLink }}}
1011
{{{ renderResourceHints() }}}
1112
{{{ renderStyles() }}}
1213
</head>

packages/@vuepress/core/lib/client/root-mixins/updateMeta.js

+29
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default {
1313
this.$ssrContext.title = this.$title
1414
this.$ssrContext.lang = this.$lang
1515
this.$ssrContext.pageMeta = renderPageMeta(mergedMetaItems)
16+
this.$ssrContext.canonicalLink = renderCanonicalLink(this.$canonicalUrl)
1617
}
1718
},
1819
// Other life cycles will only be called at client
@@ -22,6 +23,7 @@ export default {
2223

2324
// update title / meta tags
2425
this.updateMeta()
26+
this.updateCanonicalLink()
2527
},
2628

2729
methods: {
@@ -39,18 +41,45 @@ export default {
3941
// description needs special attention as it has too many entries
4042
return unionBy([{ name: 'description', content: this.$description }],
4143
pageMeta, this.siteMeta, metaIdentifier)
44+
},
45+
46+
updateCanonicalLink () {
47+
removeCanonicalLink()
48+
49+
if (!this.$canonicalUrl) {
50+
return
51+
}
52+
53+
document.head.insertAdjacentHTML('beforeend', renderCanonicalLink(this.$canonicalUrl))
4254
}
4355
},
4456

4557
watch: {
4658
$page () {
4759
this.updateMeta()
60+
this.updateCanonicalLink()
4861
}
4962
},
5063

5164
beforeDestroy () {
5265
updateMetaTags(null, this.currentMetaTags)
66+
removeCanonicalLink()
67+
}
68+
}
69+
70+
function removeCanonicalLink () {
71+
const canonicalEl = document.querySelector("link[rel='canonical']")
72+
73+
if (canonicalEl) {
74+
canonicalEl.remove()
75+
}
76+
}
77+
78+
function renderCanonicalLink (link = '') {
79+
if (!link) {
80+
return ''
5381
}
82+
return `<link href="${link}" rel="canonical" />`
5483
}
5584

5685
/**

packages/@vuepress/core/lib/node/ClientComputedMixin.js

+10
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ module.exports = siteData => {
6565
return this.$localeConfig.title || this.$site.title || ''
6666
}
6767

68+
get $canonicalUrl () {
69+
const { canonical } = this.$page.frontmatter
70+
71+
if (typeof canonical === 'string') {
72+
return canonical
73+
}
74+
75+
return false
76+
}
77+
6878
get $title () {
6979
const page = this.$page
7080
const { metaTitle } = this.$page.frontmatter

packages/docs/docs/guide/frontmatter.md

+7
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,13 @@ meta:
110110
---
111111
```
112112

113+
### canonicalUrl <Badge text="1.7.0+" />
114+
115+
- Type: `string`
116+
- Default: `undefined`
117+
118+
Set the canonical URL for the current page.
119+
113120
## Predefined Variables Powered By Default Theme
114121

115122
### navbar

0 commit comments

Comments
 (0)