diff --git a/docusaurus.config.ts b/docusaurus.config.ts index c14ef214..c6d41909 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -136,10 +136,23 @@ const config = (async (): Promise => { createSitemapItems: async (params) => { const { defaultCreateSitemapItems, ...rest } = params; const items = await defaultCreateSitemapItems(rest); - return items.map((item) => { + const COMMUNITY_YEAR_RE = /^\/community\/(\d{4})[-/]/; + return items.flatMap((item) => { // Use pathname so priorities work on deploy previews too const path = new URL(item.url).pathname; + // Community meeting/transcript dated content: + // 2026 → priority 0.9 (current cadence we want indexed) + // pre-2026 → noindex (handled in CommunityPostPage swizzle); drop from sitemap + const communityYearMatch = path.match(COMMUNITY_YEAR_RE); + if (communityYearMatch) { + const year = Number(communityYearMatch[1]); + if (year >= 2026) { + return [{ ...item, priority: 0.9, changefreq: 'monthly' }]; + } + return []; + } + // Homepage — highest priority if (path === '/') { return { ...item, priority: 1.0, changefreq: 'daily' }; @@ -147,10 +160,15 @@ const config = (async (): Promise => { // v2 docs (current, no version prefix) — high priority if (path.startsWith('/docs/') && !path.startsWith('/docs/v1/') && !path.startsWith('/docs/0.82/')) { + // Docs landing — top priority alongside homepage + if (path === '/docs/') { + return { ...item, priority: 1.0, changefreq: 'weekly' }; + } + // SEO-critical: component model, kubernetes, quickstart, overview if ( - path === '/docs/' || path.startsWith('/docs/quickstart/') || - path.startsWith('/docs/overview/') + path.startsWith('/docs/overview/') || + path.startsWith('/docs/kubernetes-operator/') ) { return { ...item, priority: 0.9, changefreq: 'weekly' }; } @@ -168,17 +186,22 @@ const config = (async (): Promise => { return { ...item, priority: 0.7, changefreq: 'monthly' }; } - // Community meeting notes + // Community meeting notes & transcripts if (path.startsWith('/community/') || path === '/community/') { if (path === '/community/' || path === '/community') { - return { ...item, priority: 0.7, changefreq: 'weekly' }; + return { ...item, priority: 0.7, changefreq: 'monthly' }; + } + // Pagination/tag archives — low priority + if (path.startsWith('/community/page/') || path.startsWith('/community/tags/')) { + return { ...item, priority: 0.3, changefreq: 'weekly' }; } - return { ...item, priority: 0.5, changefreq: 'weekly' }; + // Individual meeting notes & transcripts + return { ...item, priority: 0.5, changefreq: 'monthly' }; } - // v1 docs — deprioritized + // v1 docs — archived if (path.startsWith('/docs/v1/')) { - return { ...item, priority: 0.3, changefreq: 'monthly' }; + return { ...item, priority: 0.3, changefreq: 'yearly' }; } // 0.82 docs — already disallowed in robots.txt, minimal priority diff --git a/src/theme/wasmcloud/community/post-page/index.tsx b/src/theme/wasmcloud/community/post-page/index.tsx index 59961dd5..fd228e41 100644 --- a/src/theme/wasmcloud/community/post-page/index.tsx +++ b/src/theme/wasmcloud/community/post-page/index.tsx @@ -1,5 +1,6 @@ import React, { type ReactNode } from 'react'; import clsx from 'clsx'; +import Head from '@docusaurus/Head'; import { HtmlClassNameProvider, ThemeClassNames } from '@docusaurus/theme-common'; import { BlogPostProvider, useBlogPost } from '@docusaurus/plugin-content-blog/client'; import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata'; @@ -13,6 +14,21 @@ import CommunityPostItem from '../post-item'; import Link from '@docusaurus/Link'; import VideoSEO from '../video-seo'; +// Community meetings & transcripts older than 2026 are no longer current. Tell +// search engines not to index them, but keep `follow` so they still pass link +// equity to current pages they reference. Sitemap config (docusaurus.config.ts) +// drops these URLs from sitemap.xml in parallel. +function NoindexIfArchived(): JSX.Element | null { + const { metadata } = useBlogPost(); + const year = new Date(metadata.date).getUTCFullYear(); + if (year >= 2026) return null; + return ( + + + + ); +} + function CommunityPostPageContent({ children }: { children: ReactNode }): JSX.Element { const { metadata, toc } = useBlogPost(); const { frontMatter, unlisted } = metadata; @@ -68,6 +84,7 @@ export default function CommunityPostPage(props: Props): JSX.Element { > +