nuxt-schema-org
Version:
The quickest and easiest way to build Schema.org graphs for Nuxt.
222 lines (216 loc) • 7.94 kB
JavaScript
const kit = require('@nuxt/kit');
const schemaOrg = require('@unhead/schema-org');
const vue = require('@unhead/schema-org/vue');
const defu = require('defu');
const kit$1 = require('nuxt-site-config/kit');
const pkgTypes = require('pkg-types');
const node_fs = require('node:fs');
const pathe = require('pathe');
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
const DEVTOOLS_UI_ROUTE = "/__nuxt-schema-org";
const DEVTOOLS_UI_LOCAL_PORT = 3030;
function setupDevToolsUI(options, resolve, nuxt = kit.useNuxt()) {
const clientPath = resolve("./client");
const isProductionBuild = node_fs.existsSync(clientPath);
if (isProductionBuild) {
nuxt.hook("vite:serverCreated", async (server) => {
const sirv = await import('sirv').then((r) => r.default || r);
server.middlewares.use(
DEVTOOLS_UI_ROUTE,
sirv(clientPath, { dev: true, single: true })
);
});
} else {
nuxt.hook("vite:extendConfig", (config) => {
config.server = config.server || {};
config.server.proxy = config.server.proxy || {};
config.server.proxy[DEVTOOLS_UI_ROUTE] = {
target: `http://localhost:${DEVTOOLS_UI_LOCAL_PORT}${DEVTOOLS_UI_ROUTE}`,
changeOrigin: true,
followRedirects: true,
rewrite: (path) => path.replace(DEVTOOLS_UI_ROUTE, "")
};
});
}
nuxt.hook("devtools:customTabs", (tabs) => {
tabs.push({
// unique identifier
name: "nuxt-schema-org",
// title to display in the tab
title: "Schema.org",
// any icon from Iconify, or a URL to an image
icon: "carbon:chart-relationship",
// iframe view
view: {
type: "iframe",
src: DEVTOOLS_UI_ROUTE
}
});
});
}
function extendTypes(module, template) {
const nuxt = kit.useNuxt();
const { resolve } = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('module.cjs', document.baseURI).href)));
kit.addTemplate({
filename: `module/${module}.d.ts`,
getContents: async () => {
const typesPath = pathe.relative(resolve(nuxt.options.rootDir, nuxt.options.buildDir, "module"), resolve("runtime/types"));
const s = await template({ typesPath });
return `// Generated by ${module}
${s}
export {}
`;
}
});
nuxt.hooks.hook("prepare:types", ({ references }) => {
references.push({ path: resolve(nuxt.options.buildDir, `module/${module}.d.ts`) });
});
}
const module$1 = kit.defineNuxtModule({
meta: {
name: "nuxt-schema-org",
configKey: "schemaOrg",
compatibility: {
nuxt: ">=3.16.0"
},
moduleDependencies: {
"@nuxtjs/i18n": {
version: ">=8",
optional: true
},
"nuxt-i18n-micro": {
version: ">=1",
optional: true
},
"nuxt-site-config": {
version: ">=3"
},
"@nuxt/content": {
version: ">=2",
optional: true
}
}
},
defaults(nuxt) {
return {
enabled: true,
defaults: true,
reactive: nuxt.options.dev || !nuxt.options.ssr,
minify: !nuxt.options.dev,
scriptAttributes: {
"data-nuxt-schema-org": true
}
};
},
async setup(config, nuxt) {
const { resolve } = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('module.cjs', document.baseURI).href)));
const { name, version } = await pkgTypes.readPackageJSON(resolve("../package.json"));
const logger = kit.useLogger(name);
logger.level = config.debug ? 4 : 3;
if (config.enabled === false) {
logger.debug("The module is disabled, skipping setup.");
return;
}
if (!nuxt.options.ssr && nuxt.options.dev)
logger.warn("You are using Schema.org with SSR disabled. This is not recommended, Google may not detect your Schema.org, and it adds extra page weight");
await kit$1.installNuxtSiteConfig();
const runtimeConfig = {
reactive: config.reactive,
minify: config.minify,
scriptAttributes: config.scriptAttributes,
identity: config.identity,
version
};
if (config.reactive)
nuxt.options.runtimeConfig.public["nuxt-schema-org"] = runtimeConfig;
nuxt.options.runtimeConfig["nuxt-schema-org"] = runtimeConfig;
const pluginPath = kit.hasNuxtModule("@nuxtjs/i18n") && nuxt.options.i18n?.locales ? "./runtime/app/plugins/i18n" : "./runtime/app/plugins";
kit.addPlugin({
src: resolve(pluginPath, "init"),
mode: config.reactive ? "all" : "server"
});
if (config.defaults) {
kit.addPlugin({
src: resolve(pluginPath, "defaults"),
mode: config.reactive ? "all" : "server"
});
}
nuxt.options.alias["#schema-org"] = resolve("./runtime");
const usingNuxtContent = kit.hasNuxtModule("@nuxt/content");
const isNuxtContentV3 = usingNuxtContent && await kit.hasNuxtModuleCompatibility("@nuxt/content", "^3");
const isNuxtContentV2 = usingNuxtContent && await kit.hasNuxtModuleCompatibility("@nuxt/content", "^2");
if (isNuxtContentV3) {
nuxt.hooks.hook("content:file:afterParse", (ctx) => {
if (typeof ctx.content.schemaOrg === "undefined") {
return;
}
const content = ctx.content;
const nodes = Array.isArray(content.schemaOrg) ? content.schemaOrg : [schemaOrg.defineWebPage(content.schemaOrg)];
const replaceType = (node) => {
if (node.type) {
node["@type"] = node.type;
delete node.type;
}
Object.entries(node).forEach(([, value]) => {
if (typeof value === "object") {
replaceType(value);
}
});
return node;
};
const script = {
type: "application/ld+json",
key: "schema-org-graph",
...config.scriptAttributes,
nodes: nodes.map(replaceType)
};
content.head = defu.defu({ script: [script] }, content.head);
ctx.content = content;
});
} else if (isNuxtContentV2) {
kit.addServerPlugin(resolve("./runtime/server/plugins/nuxt-content-v2"));
}
if (!config.reactive)
nuxt.options.optimization.treeShake.composables.client["nuxt-schema-org"] = vue.schemaOrgAutoImports[0].imports;
for (const component of vue.schemaOrgComponents) {
await kit.addComponent({
name: component,
export: component,
chunkName: "nuxt-schema-org/components",
filePath: "@unhead/schema-org/vue"
});
}
kit.addImports({
from: resolve("./runtime/app/composables/useSchemaOrg"),
name: "useSchemaOrg"
});
nuxt.hooks.hook("imports:sources", (autoImports) => {
vue.schemaOrgAutoImports[0].imports = vue.schemaOrgAutoImports[0].imports.filter((i) => i !== "useSchemaOrg");
autoImports.unshift(...vue.schemaOrgAutoImports);
});
extendTypes("nuxt-schema-org", ({ typesPath }) => {
return `
declare module '@nuxt/schema' {
export interface RuntimeNuxtHooks {
'schema-org:meta': (meta: import('${typesPath}').MetaInput) => void | Promise<void>
}
}
declare module '#app' {
export interface RuntimeNuxtHooks {
'schema-org:meta': (meta: import('${typesPath}').MetaInput) => void | Promise<void>
}
}
`;
});
if (config.debug || nuxt.options.dev) {
kit.addServerHandler({
route: "/__schema-org__/debug.json",
handler: resolve("./runtime/server/routes/__schema-org__/debug")
});
}
if (nuxt.options.dev)
setupDevToolsUI(config, resolve);
}
});
module.exports = module$1;
;