2025-09-05 14:59:21 +08:00

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 });
};