feat: noindex for declared and signed-in routes
- app plugin seo-route-robots: a page whose meta sets requiresAuth: true gets robots noindex, nofollow, a page with seo.robots gets its value, a path under seo.noindexRoutes gets noindex, nofollow; meta tag above the CMS head entry and X-Robots-Tag during SSR, never on staging - requiresAuth and seo added to Nuxt's page meta extraction keys - playground /konto, /szkic and /prywatne with their smoke lines
This commit is contained in:
50
app/plugins/seo-route-robots.ts
Normal file
50
app/plugins/seo-route-robots.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// Noindex for the routes an app declares (D-23, D-21), without page code:
|
||||
//
|
||||
// - a page whose meta sets requiresAuth: true (a signed-in or auth page)
|
||||
// gets robots "noindex, nofollow";
|
||||
// - a page whose meta sets seo: { robots: '...' } gets that value;
|
||||
// - a path under seo.noindexRoutes gets "noindex, nofollow" (its route
|
||||
// rule already sends the header; this adds the meta tag).
|
||||
//
|
||||
// The value goes into a robots meta tag that wins over the CMS's (a lower
|
||||
// tagPriority than the head plugin's 'critical') and, during SSR, into the
|
||||
// X-Robots-Tag header once the navigation is done, after the route
|
||||
// middleware. Every other page keeps the CMS robots; on staging the CMS's
|
||||
// noindex, nofollow stays. Works with the layer off too: it reads no CMS.
|
||||
|
||||
import { isNoindex } from '../../lib/guard.ts'
|
||||
import { pageMetaRobots } from '../../lib/routes.ts'
|
||||
|
||||
/** Wins over the CMS head entry (tagPriority 'critical', -8). */
|
||||
const ROUTE_ROBOTS_PRIORITY = -10
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
const config = useRuntimeConfig()
|
||||
const declared = (config.public.seo as { noindexRoutes?: unknown } | undefined)?.noindexRoutes
|
||||
const noindexRoutes = Array.isArray(declared) ? declared.filter((p): p is string => typeof p === 'string') : []
|
||||
const router = useRouter()
|
||||
const answer = useSeoAnswer()
|
||||
|
||||
const robotsFor = (route: { path: string; meta: Record<string, unknown> }): string | null => {
|
||||
if (answer.value?.staging === true) return null
|
||||
const own = pageMetaRobots(route.meta)
|
||||
if (own) return own
|
||||
return isNoindex(route.path, noindexRoutes) ? 'noindex, nofollow' : null
|
||||
}
|
||||
|
||||
useHead(
|
||||
computed(() => {
|
||||
const robots = robotsFor(router.currentRoute.value)
|
||||
return robots ? { meta: [{ name: 'robots', content: robots }] } : {}
|
||||
}),
|
||||
{ tagPriority: ROUTE_ROBOTS_PRIORITY },
|
||||
)
|
||||
|
||||
if (import.meta.server) {
|
||||
router.afterEach((to, _from, failure) => {
|
||||
if (failure) return
|
||||
const robots = robotsFor(to)
|
||||
if (robots) nuxtApp.runWithContext(() => (useResponseHeader('X-Robots-Tag').value = robots))
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user