-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
54 lines (50 loc) · 1.82 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const seoGuard = async (route, fallbackTitle='') => {
const nearestWithTitle = findNearest(route, r => r?.meta?.seo?.title);
const nearestWithMeta = findNearest(route, r => r?.meta?.seo?.metaTags);
const nearestWithRichSnippet = findNearest(route, r => r?.meta?.seo?.richSnippet);
if( nearestWithTitle ) {
const { title } = nearestWithTitle.meta.seo;
if (typeof title === 'function') {
document.title = await Promise.resolve().then(() => title(route));
} else {
document.title = title;
}
}
else { document.title = fallbackTitle; }
Array.from(document.querySelectorAll('[data-vue-router-controlled]')).map(el => el.parentNode.removeChild(el));
if ( nearestWithMeta ) {
const { metaTags } = nearestWithMeta.meta.seo;
let tags = metaTags;
if (typeof metaTags === 'function') {
tags = await Promise.resolve().then(() => metaTags(route));
}
tags.map(tagDef => {
const tag = document.createElement('meta');
Object.keys(tagDef).forEach(async key => {
if (typeof tagDef[key] === 'function') {
tag.setAttribute(key, await tagDef[key](route));
} else {
tag.setAttribute(key, tagDef[key]);
}
});
tag.setAttribute('data-vue-router-controlled', '');
return tag;
}).forEach(tag => document.head.appendChild(tag));
}
if ( nearestWithRichSnippet ) {
const snippet = JSON.stringify(nearestWithRichSnippet.meta.seo.richSnippet);
const tag = document.createElement('script');
tag.setAttribute('type', 'application/ld+json');
tag.setAttribute('data-vue-router-controlled', '');
tag.text = snippet;
document.head.appendChild(tag);
}
};
const seoGuardWithNext = async (to, from, next, fallbackTitle='') => {
await seoGuard(to, fallbackTitle);
next();
}
export { seoGuard, seoGuardWithNext }
function findNearest (route, filter) {
return route.matched.slice().reverse().find(filter);
}