doc.yeswiki.pro/node_modules/vitepress/dist/client/app/composables/head.js
2023-05-20 19:38:02 +03:00

51 lines
1.9 KiB
JavaScript

import { watchEffect } from 'vue';
import { createTitle, mergeHead } from '../../shared';
export function useUpdateHead(route, siteDataByRouteRef) {
let managedHeadTags = [];
let isFirstUpdate = true;
const updateHeadTags = (newTags) => {
if (import.meta.env.PROD && isFirstUpdate) {
// in production, the initial meta tags are already pre-rendered so we
// skip the first update.
isFirstUpdate = false;
return;
}
managedHeadTags.forEach((el) => document.head.removeChild(el));
managedHeadTags = [];
newTags.forEach((headConfig) => {
const el = createHeadElement(headConfig);
document.head.appendChild(el);
managedHeadTags.push(el);
});
};
watchEffect(() => {
const pageData = route.data;
const siteData = siteDataByRouteRef.value;
const pageDescription = pageData && pageData.description;
const frontmatterHead = (pageData && pageData.frontmatter.head) || [];
// update title and description
document.title = createTitle(siteData, pageData);
document
.querySelector(`meta[name=description]`)
.setAttribute('content', pageDescription || siteData.description);
updateHeadTags(mergeHead(siteData.head, filterOutHeadDescription(frontmatterHead)));
});
}
function createHeadElement([tag, attrs, innerHTML]) {
const el = document.createElement(tag);
for (const key in attrs) {
el.setAttribute(key, attrs[key]);
}
if (innerHTML) {
el.innerHTML = innerHTML;
}
return el;
}
function isMetaDescription(headConfig) {
return (headConfig[0] === 'meta' &&
headConfig[1] &&
headConfig[1].name === 'description');
}
function filterOutHeadDescription(head) {
return head.filter((h) => !isMetaDescription(h));
}