diff --git a/docs/content/3.advanced/2.content.md b/docs/content/3.advanced/2.content.md index 15f384a6..892e2138 100644 --- a/docs/content/3.advanced/2.content.md +++ b/docs/content/3.advanced/2.content.md @@ -12,6 +12,8 @@ relatedPages: Nuxt Robots comes with an integration for Nuxt Content that allows you to configure robots straight from your markdown directly. +The integration needs Nuxt Content v3. Nuxt Robots v7 does not support Nuxt Content v2. + ## Setup Nuxt Content v3 Add `defineRobotsSchema()`{lang="ts"} to your collection's schema to enable the `robots` frontmatter key. @@ -93,17 +95,6 @@ useRobotsRule(page.value?.robots ?? undefined) See [Usage](#usage) for the values the `robots` key accepts. -## Setup Nuxt Content v2 - -In Nuxt Content v2 markdown files require either [Document Driven Mode](https://content.nuxt.com/document-driven/introduction) or a `path` key to be set -in the frontmatter. - -```md [content/foo.md] ---- -path: /foo ---- -``` - ## Usage You can use any boolean or string value as `robots` that will be forwarded as a diff --git a/src/module.ts b/src/module.ts index afd1b27d..c00ab61b 100644 --- a/src/module.ts +++ b/src/module.ts @@ -219,7 +219,7 @@ export default defineNuxtModule({ version: '>=5.0.0', }, '@nuxt/content': { - version: '>=2', + version: '>=3', optional: true, }, '@harlan-zw/comark-content': { @@ -470,11 +470,9 @@ export default defineNuxtModule({ const nitroPreset = resolveNitroPreset(nuxt.options.nitro) const contentProvider = await resolveContentProvider(nuxt) const isNuxtContentV3 = contentProvider._tag === 'NuxtContent' && contentProvider.version === 3 - let isNuxtContentV2 = !config.disableNuxtContentIntegration && contentProvider._tag === 'NuxtContent' && contentProvider.version === 2 const isComarkContent = contentProvider._tag === 'Comark' // comark-content fires the same build hook with the same context shape, so the - // frontmatter mapping is identical. It reads Markdown into Nitro server assets - // rather than a database, so unlike Nuxt Content v2 it needs no Cloudflare opt out. + // frontmatter mapping is identical. if (!config.disableNuxtContentIntegration && (isNuxtContentV3 || isComarkContent)) { nuxt.hooks.hook('content:file:afterParse' as any, (ctx: FileAfterParseHook) => { if (ctx.content.robots != null) { @@ -491,10 +489,6 @@ export default defineNuxtModule({ } }) } - else if (isNuxtContentV2 && nitroPreset.startsWith('cloudflare')) { - logger.warn('The Nuxt Robots, Nuxt Content integration does not work with CloudFlare yet, the integration will be disabled. Learn more at: https://nuxtseo.com/docs/robots/guides/content') - isNuxtContentV2 = false - } nuxt.hook('nitro:build:public-assets', (nitro: any) => { nitro.hooks.hook('close', async () => { @@ -608,7 +602,6 @@ export default defineNuxtModule({ const robotsRuntimeConfig: NuxtRobotsRuntimeConfig = { version: version || '', - isNuxtContentV2, debug: config.debug, credits: config.credits, groups, @@ -667,13 +660,6 @@ export default defineNitroPlugin((nitroApp) => { }).filename) } - if (isNuxtContentV2) { - addServerHandler({ - route: '/__robots__/nuxt-content.json', - handler: resolve('./runtime/server/routes/__robots__/nuxt-content-v2'), - }) - } - if (config.debug || nuxt.options.dev) { addServerHandler({ route: '/__robots__/debug.json', diff --git a/src/runtime/server/composables/getPathRobotConfig.ts b/src/runtime/server/composables/getPathRobotConfig.ts index ed458d10..794f6ad7 100644 --- a/src/runtime/server/composables/getPathRobotConfig.ts +++ b/src/runtime/server/composables/getPathRobotConfig.ts @@ -39,7 +39,7 @@ function parseRuntimeI18nConfig(input: unknown): RuntimeI18nConfig | null { export function getPathRobotConfig(e: RequestEvent, options?: { userAgent?: string, skipSiteIndexable?: boolean, path?: string }): RobotsContext { const runtimeConfig = useRuntimeConfig() // has already been resolved - const { robotsDisabledValue, robotsEnabledValue, isNuxtContentV2 } = useRuntimeConfigNuxtRobots(e) + const { robotsDisabledValue, robotsEnabledValue } = useRuntimeConfigNuxtRobots(e) if (!options?.skipSiteIndexable) { if (!getSiteRobotConfig(e).indexable) { return { @@ -108,18 +108,7 @@ export function getPathRobotConfig(e: RequestEvent, options?: { userAgent?: stri } } - // 2. nuxt content rules - if (isNuxtContentV2 && nitroApp._robots?.nuxtContentUrls?.has(withoutTrailingSlash(path))) { - return { - indexable: false, - rule: robotsDisabledValue, - debug: { - source: 'Nuxt Content', - }, - } - } - - // 3. nitro route rules + // 2. nitro route rules const baseURL = runtimeConfig.app.baseURL const matchRules = (pathOrUrl: string) => matchRouteRules(withoutBase(withoutTrailingSlash((pathOrUrl.startsWith('/') ? pathOrUrl : parseURL(pathOrUrl, baseURL).pathname).split('?')[0]!), baseURL)) let robotRouteRules = matchRules(path) @@ -145,7 +134,7 @@ export function getPathRobotConfig(e: RequestEvent, options?: { userAgent?: stri }, } } - // 4. page meta robots + // 3. page meta robots const pagePath = withoutBase(parseURL(path).pathname || '/', runtimeConfig.app.baseURL) const pageMetaRule = pageMetaMatchers.find((page: { re: RegExp }) => page.re.test(pagePath))?.robots if (typeof pageMetaRule !== 'undefined') { diff --git a/src/runtime/server/plugins/initContext.ts b/src/runtime/server/plugins/initContext.ts index 98f166cb..a4626d0d 100644 --- a/src/runtime/server/plugins/initContext.ts +++ b/src/runtime/server/plugins/initContext.ts @@ -1,11 +1,9 @@ import { createPatternMap } from '@nuxtjs/robots/util' import { getRouteRules } from 'nuxt/server' -import { withoutTrailingSlash } from 'ufo' // @ts-expect-error Virtual server template registered by the module. import { ROBOTS_SSR_DEFAULT } from '#nuxt-robots/ssr-default.mjs' import { defineNitroPlugin } from '#nuxtseo/nitro' import { useRuntimeConfigNuxtRobots } from '../composables/useRuntimeConfigNuxtRobots' -import { logger } from '../logger' import { resolveRobotsTxtContext } from '../util' const PRERENDER_NO_SSR_ROUTES = new Set(['/index.html', '/200.html', '/404.html']) @@ -13,7 +11,7 @@ const PRERENDER_NO_SSR_ROUTES = new Set(['/index.html', '/200.html', '/404.html' // we need to init our state using a nitro plugin so the user doesn't throttle the resolve context hook // important when we integrate with nuxt-simple-sitemap and we're checking thousands of URLs export default defineNitroPlugin(async (nitroApp) => { - const { isNuxtContentV2, robotsDisabledValue, botDetection } = useRuntimeConfigNuxtRobots() + const { robotsDisabledValue, botDetection } = useRuntimeConfigNuxtRobots() // Initialize bot detection pattern map if enabled if (botDetection !== false) { @@ -22,22 +20,6 @@ export default defineNitroPlugin(async (nitroApp) => { nitroApp._robots = {} as typeof nitroApp._robots await resolveRobotsTxtContext(undefined, nitroApp) - const nuxtContentUrls = new Set() - if (isNuxtContentV2) { - let urls: string[] | undefined - try { - urls = await (await nitroApp.localFetch('/__robots__/nuxt-content.json', {})).json() - } - catch (e) { - logger.error('Failed to read robot rules from content files.', e) - } - if (urls && Array.isArray(urls) && urls.length) { - urls.forEach((url: string) => nuxtContentUrls.add(withoutTrailingSlash(url))) - } - } - if (nuxtContentUrls.size) { - nitroApp._robots.nuxtContentUrls = nuxtContentUrls - } if (import.meta.prerender) { // need to inject HTML if we have an SPA route diff --git a/src/runtime/server/routes/__robots__/nuxt-content-v2.ts b/src/runtime/server/routes/__robots__/nuxt-content-v2.ts deleted file mode 100644 index a54983c8..00000000 --- a/src/runtime/server/routes/__robots__/nuxt-content-v2.ts +++ /dev/null @@ -1,26 +0,0 @@ -// @ts-expect-error v3 installed -import type { ParsedContent } from '@nuxt/content' -import { defineEventHandler } from 'nuxt/server' -// @ts-expect-error alias module -import { serverQueryContent } from '#content/server' -import { logger } from '../../logger' - -export default defineEventHandler(async (e) => { - const content: ParsedContent[] = [] - try { - content.push(...(await serverQueryContent(e).find()) as ParsedContent[]) - } - catch (e) { - logger.error('Error querying Nuxt content', e) - } - return content.map((c) => { - if (c._draft || c._extension !== 'md' || c._partial) - return false - if (c.path) { - if (String(c.robots) === 'false') - return c.path - } - return false - }) - .filter(Boolean) -}) diff --git a/src/runtime/server/routes/robots-txt.ts b/src/runtime/server/routes/robots-txt.ts index 4dc0d047..d5f42e35 100644 --- a/src/runtime/server/routes/robots-txt.ts +++ b/src/runtime/server/routes/robots-txt.ts @@ -1,17 +1,16 @@ import type { HookRobotsConfigContext, HookRobotsTxtContext, RobotsRouteRuleConfig } from '../../types' import { asArray, generateRobotsTxt, isNoIndexRule, normaliseRobotsRouteRule } from '@nuxtjs/robots/util' -import { createError, defineEventHandler, serverFetch, useRuntimeConfig } from 'nuxt/server' +import { defineEventHandler, useRuntimeConfig } from 'nuxt/server' import { useNitroApp } from '#nuxtseo/nitro' import { withSiteUrl } from '#site-config/server' import { getSiteRobotConfig } from '../composables/getSiteRobotConfig' import { useRuntimeConfigNuxtRobots } from '../composables/useRuntimeConfigNuxtRobots' -import { logger } from '../logger' import { resolveRobotsTxtContext } from '../util' export default defineEventHandler(async (e) => { const nitroApp = useNitroApp() const { indexable, hints } = getSiteRobotConfig(e) - const { credits, isNuxtContentV2, cacheControl, robotsDisabledValue } = useRuntimeConfigNuxtRobots(e) + const { credits, cacheControl, robotsDisabledValue } = useRuntimeConfigNuxtRobots(e) // move towards deprecating indexable let robotsTxtCtx: Omit = { errors: [], @@ -34,30 +33,6 @@ export default defineEventHandler(async (e) => { // validate sitemaps are absolute .map(s => !s.startsWith('http') ? withSiteUrl(e, s, { withBase: true, absolute: true }) : s), )] - if (isNuxtContentV2) { - const contentResponse = await serverFetch(e, '/__robots__/nuxt-content.json', { - headers: { - Accept: 'application/json', - }, - }) - if (!contentResponse.ok) - throw createError({ status: contentResponse.status, statusText: contentResponse.statusText }) - const contentWithRobotRules = await contentResponse.json() as string[] - // ensure it's valid json - if (String(contentWithRobotRules).trim().startsWith(' }, _robotsPatternMap?: Map`, },