UNPKG

nuxt-schema-org

Version:

The quickest and easiest way to build Schema.org graphs for Nuxt.

100 lines (99 loc) 3.19 kB
import { injectHead, useHead } from "#imports"; import { useSiteConfig } from "#site-config/app/composables/useSiteConfig"; import { createSitePathResolver } from "#site-config/app/composables/utils"; import { SchemaOrgUnheadPlugin } from "@unhead/schema-org/vue"; import { useRoute } from "nuxt/app"; import { camelCase } from "scule"; import { withTrailingSlash } from "ufo"; import { computed, toValue, watch } from "vue"; import { useSchemaOrg } from "../composables/useSchemaOrg.js"; import { useSchemaOrgConfig } from "./config.js"; export function initPlugin(nuxtApp) { const head = injectHead(); const config = useSchemaOrgConfig(); const route = useRoute(); const siteConfig = useSiteConfig(); const resolvePath = createSitePathResolver({ absolute: false, withBase: true }); const resolveUrl = createSitePathResolver({ canonical: true, absolute: true, withBase: true }); const schemaOrg = computed(() => { const siteConfigResolved = {}; for (const key in siteConfig) { if (key.startsWith("_")) { continue; } siteConfigResolved[key] = toValue(siteConfig[key]); if (typeof siteConfigResolved[key] === "object") { for (const k in siteConfigResolved[key]) { siteConfigResolved[key][k] = toValue(siteConfigResolved[key][k]); } } } return { ...route.meta?.schemaOrg || {}, ...siteConfigResolved, url: toValue(resolveUrl(route.path)), host: withTrailingSlash(siteConfigResolved.url), inLanguage: toValue(siteConfigResolved.currentLocale) || toValue(siteConfigResolved.defaultLocale), path: toValue(resolvePath(route.path)) }; }); const templateParamEntry = useHead({ templateParams: { schemaOrg: schemaOrg.value } }); watch(() => siteConfig, () => { templateParamEntry.patch({ templateParams: { schemaOrg: schemaOrg.value } }); }, { deep: true }); head.use( SchemaOrgUnheadPlugin({}, async () => { const meta = {}; await nuxtApp.hooks.callHook("schema-org:meta", meta); return meta; }, { minify: config.minify, trailingSlash: siteConfig.trailingSlash }) ); } export function maybeAddIdentitySchemaOrg() { const config = useSchemaOrgConfig(); const siteConfig = useSiteConfig({ resolveRefs: true }); if (config.identity || siteConfig.identity) { const identity = config.identity || siteConfig.identity; let identityPayload = { name: () => toValue(siteConfig.name), url: () => toValue(siteConfig.url) }; let identityType; if (typeof identity !== "string") { identityPayload = { ...identityPayload, ...identity }; identityType = identity.type; delete identityPayload.type; } else { identityType = identity; } if (siteConfig.twitter) { const id = siteConfig.twitter.startsWith("@") ? siteConfig.twitter.slice(1) : siteConfig.twitter; identityPayload.sameAs = [ `https://twitter.com/${id}` ]; } identityPayload._resolver = identityPayload._resolver || camelCase(identityType); useSchemaOrg([identityPayload]); } }