95 lines
3.1 KiB
JavaScript
95 lines
3.1 KiB
JavaScript
import { hasProtocol, joinURL, withTrailingSlash, withoutTrailingSlash } from "ufo";
|
|
import { useRoute, nextTick, useHead, unref, watch, useRuntimeConfig } from "#imports";
|
|
export const useContentHead = (_content, to = useRoute()) => {
|
|
const content = unref(_content);
|
|
const config = useRuntimeConfig();
|
|
const refreshHead = (data = content) => {
|
|
if (!to.path || !data) {
|
|
return;
|
|
}
|
|
const head = Object.assign({}, data?.head || {});
|
|
head.meta = [...head.meta || []];
|
|
head.link = [...head.link || []];
|
|
const title = head.title || data?.title;
|
|
if (title) {
|
|
head.title = title;
|
|
if (import.meta.server && !head.meta.some((m) => m.property === "og:title")) {
|
|
head.meta.push({
|
|
property: "og:title",
|
|
content: title
|
|
});
|
|
}
|
|
}
|
|
const host = config.public.content.host;
|
|
if (import.meta.server && host) {
|
|
const _url = joinURL(host ?? "/", config.app.baseURL, to.fullPath);
|
|
const url = config.public.content.trailingSlash ? withTrailingSlash(_url) : withoutTrailingSlash(_url);
|
|
if (!head.meta.some((m) => m.property === "og:url")) {
|
|
head.meta.push({
|
|
property: "og:url",
|
|
content: url
|
|
});
|
|
}
|
|
if (!head.link.some((m) => m.rel === "canonical")) {
|
|
head.link.push({
|
|
rel: "canonical",
|
|
href: url
|
|
});
|
|
}
|
|
}
|
|
const description = head?.description || data?.description;
|
|
if (description && head.meta.filter((m) => m.name === "description").length === 0) {
|
|
head.meta.push({
|
|
name: "description",
|
|
content: description
|
|
});
|
|
}
|
|
if (import.meta.server && description && !head.meta.some((m) => m.property === "og:description")) {
|
|
head.meta.push({
|
|
property: "og:description",
|
|
content: description
|
|
});
|
|
}
|
|
const image = head?.image || data?.image;
|
|
if (import.meta.server && image && head.meta.filter((m) => m.property === "og:image").length === 0) {
|
|
if (typeof image === "string") {
|
|
head.meta.push({
|
|
property: "og:image",
|
|
content: host && !hasProtocol(image) ? new URL(joinURL(config.app.baseURL, image), host).href : image
|
|
});
|
|
}
|
|
if (typeof image === "object") {
|
|
const imageKeys = [
|
|
"src",
|
|
"secure_url",
|
|
"type",
|
|
"width",
|
|
"height",
|
|
"alt"
|
|
];
|
|
for (const key of imageKeys) {
|
|
if (key === "src" && image.src) {
|
|
const isAbsoluteURL = hasProtocol(image.src);
|
|
const imageURL = isAbsoluteURL ? image.src : joinURL(config.app.baseURL, image.src ?? "/");
|
|
head.meta.push({
|
|
property: "og:image",
|
|
content: host && !isAbsoluteURL ? new URL(imageURL, host).href : imageURL
|
|
});
|
|
} else if (image[key]) {
|
|
head.meta.push({
|
|
property: `og:image:${key}`,
|
|
content: image[key]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (import.meta.client) {
|
|
nextTick(() => useHead(head));
|
|
} else {
|
|
useHead(head);
|
|
}
|
|
};
|
|
watch(() => unref(_content), refreshHead, { immediate: true });
|
|
};
|