From 560c98716cbed9b313e4dcbb6b75cec34e710730 Mon Sep 17 00:00:00 2001 From: Muhammad Bappi Date: Tue, 22 Sep 2026 19:41:09 +0600 Subject: [PATCH] feat: give the site a sitemap, a robots file and canonical URLs The docs half of the sitemap comes from fumadocs' own source, so a new page needs no second edit. Canonicals are trailing-slashed to match `trailingSlash`, or they would point at a redirect. The fallback OG card is a committed PNG rather than an image route because `output: export` writes that route to an extensionless file, which Pages serves as octet-stream and no unfurler accepts. --- src/app/blog/page.tsx | 1 + src/app/docs/[[...slug]]/page.tsx | 8 +++++++- src/app/layout.tsx | 11 +++++++++-- src/app/opengraph-image.alt.txt | 1 + src/app/opengraph-image.png | Bin 0 -> 55974 bytes src/app/page.tsx | 1 + src/app/robots.ts | 19 +++++++++++++++++++ src/app/sitemap.ts | 25 +++++++++++++++++++++++++ src/lib/shared.ts | 14 ++++++++++++++ 9 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 src/app/opengraph-image.alt.txt create mode 100644 src/app/opengraph-image.png create mode 100644 src/app/robots.ts create mode 100644 src/app/sitemap.ts diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx index 11ae22b..faed0f4 100644 --- a/src/app/blog/page.tsx +++ b/src/app/blog/page.tsx @@ -7,6 +7,7 @@ import { documented } from '@/lib/services/packages.service'; export const metadata: Metadata = { title: 'Blog', description: 'Writing about the Axonpack libraries. Release notes live in the changelog.', + alternates: { canonical: '/blog/' }, }; export default function BlogPage() { diff --git a/src/app/docs/[[...slug]]/page.tsx b/src/app/docs/[[...slug]]/page.tsx index 4470e24..b87d52c 100644 --- a/src/app/docs/[[...slug]]/page.tsx +++ b/src/app/docs/[[...slug]]/page.tsx @@ -12,7 +12,7 @@ import { getMDXComponents } from '@/components/mdx'; import type { Metadata } from 'next'; import { createRelativeLink } from 'fumadocs-ui/mdx'; import { findNeighbour } from 'fumadocs-core/page-tree'; -import { pageSourceUrl } from '@/lib/shared'; +import { appLongName, canonicalPath, pageSourceUrl } from '@/lib/shared'; export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { const params = await props.params; @@ -64,7 +64,13 @@ export async function generateMetadata(props: PageProps<'/docs/[[...slug]]'>): P return { title: page.data.title, description: page.data.description, + alternates: { canonical: canonicalPath(page.url) }, + // Next replaces the parent's `openGraph` rather than merging into it, so the site name has to + // be restated here or a docs page's card loses it. openGraph: { + type: 'article', + siteName: appLongName, + url: canonicalPath(page.url), images: getPageImageUrl(page).url, }, }; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a9acb25..60336d2 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,7 +3,7 @@ import { SiteFooter } from '@/components/site-footer'; import './global.css'; import type { Metadata } from 'next'; import { Chakra_Petch, JetBrains_Mono } from 'next/font/google'; -import { appLongName, appName, appTagline } from '@/lib/shared'; +import { appLongName, appName, appTagline, siteUrl } from '@/lib/shared'; // Chakra Petch has no variable cut, so every weight the site uses has to be asked for by name. const sans = Chakra_Petch({ subsets: ['latin'], weight: ['300', '400', '500', '600', '700'] }); @@ -16,11 +16,18 @@ export const metadata: Metadata = { // Every absolute URL in the metadata (OG and Twitter images, canonicals) is resolved against // this. It has to be the deployed origin, not localhost, or a shared link previews nothing. // The override is for a preview deploy on some other origin. - metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL ?? 'https://axonpack.github.io'), + metadataBase: new URL(siteUrl), // Long name when the site names itself, short as a suffix on a page that already has a title. title: { default: appLongName, template: `%s — ${appName}` }, description: appTagline, icons: { icon: '/logo.png' }, + // Inherited by every page, so a page only states what differs. `openGraph.title` is left out on + // purpose: Next fills it from the page's own resolved title, and naming it here would freeze the + // site name onto every card. + openGraph: { type: 'website', siteName: appLongName, locale: 'en_US' }, + // Without this a card unfurls as the small square thumbnail, which crops the 1200x630 image to + // an unreadable centre strip. + twitter: { card: 'summary_large_image' }, }; export default function Layout({ children }: LayoutProps<'/'>) { diff --git a/src/app/opengraph-image.alt.txt b/src/app/opengraph-image.alt.txt new file mode 100644 index 0000000..6d780f6 --- /dev/null +++ b/src/app/opengraph-image.alt.txt @@ -0,0 +1 @@ +Axonpack Open Source diff --git a/src/app/opengraph-image.png b/src/app/opengraph-image.png new file mode 100644 index 0000000000000000000000000000000000000000..a4468baf50b85eae59efa8c916f31da6f20735fb GIT binary patch literal 55974 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 literal 0 HcmV?d00001 diff --git a/src/app/page.tsx b/src/app/page.tsx index be84aa3..76c13b1 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -11,6 +11,7 @@ export const metadata: Metadata = { // The headline names the project itself now, so prefixing it with the long name said it twice. title: { absolute: `${content.hero.title} ${content.hero.titleAccent}` }, description: content.hero.lead, + alternates: { canonical: '/' }, }; /** Composes only. Each section is its own component, per the monorepo's CONVENTIONS.md. */ diff --git a/src/app/robots.ts b/src/app/robots.ts new file mode 100644 index 0000000..84704ef --- /dev/null +++ b/src/app/robots.ts @@ -0,0 +1,19 @@ +import type { MetadataRoute } from 'next'; +import { siteUrl } from '@/lib/shared'; + +/** + * Open, apart from the search index. `/api/search.json` is one big blob of every page's text, so a + * crawler that reads it gets the whole site again with none of the structure. + * + * `/llms.txt` and `/llms.mdx/` stay allowed on purpose: they exist so an agent's crawler can read + * the docs, and disallowing them would shut out the readers they were written for. + */ +// `output: 'export'` refuses to build a metadata route that has not said it is static. +export const dynamic = 'force-static'; + +export default function robots(): MetadataRoute.Robots { + return { + rules: { userAgent: '*', allow: '/', disallow: '/api/' }, + sitemap: new URL('/sitemap.xml', siteUrl).href, + }; +} diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts new file mode 100644 index 0000000..1904597 --- /dev/null +++ b/src/app/sitemap.ts @@ -0,0 +1,25 @@ +import type { MetadataRoute } from 'next'; +import { source } from '@/lib/source'; +import { canonicalPath, siteUrl } from '@/lib/shared'; + +/** + * Every static page on the site. The docs half comes from fumadocs' own source rather than a + * hand-kept list, so writing a page is the only step: there is no second place to forget. + * + * `output: 'export'` is on, so this runs once at build time and lands in `out/sitemap.xml`. + */ +// `output: 'export'` refuses to build a metadata route that has not said it is static. +export const dynamic = 'force-static'; + +export default function sitemap(): MetadataRoute.Sitemap { + const lastModified = new Date(); + + // The docs index is one of `getPages()`, so listing it here as well put it in twice. + const fixed = ['/', '/blog']; + const docs = source.getPages().map((page) => page.url); + + return [...fixed, ...docs].map((path) => ({ + url: new URL(canonicalPath(path), siteUrl).href, + lastModified, + })); +} diff --git a/src/lib/shared.ts b/src/lib/shared.ts index 08a00f5..0e660bb 100644 --- a/src/lib/shared.ts +++ b/src/lib/shared.ts @@ -33,3 +33,17 @@ export const docsRepo = { export const pageSourceUrl = (path: string) => `https://github.com/${docsRepo.user}/${docsRepo.repo}/blob/${docsRepo.branch}/content/docs/${path}`; + +/** + * The deployed origin. `metadataBase` resolves every relative URL in the metadata against it, and + * the sitemap and robots routes need it spelled out, since neither is metadata and neither sees + * `metadataBase`. The override is for a preview deploy on some other origin. + */ +export const siteUrl = process.env.NEXT_PUBLIC_SITE_URL ?? 'https://axonpack.github.io'; + +/** + * `next.config.mjs` sets `trailingSlash`, so /docs/foo is a redirect and /docs/foo/ is the page. + * A canonical or a sitemap entry pointing at the redirect asks a crawler to follow a hop to find + * the page it was already told about, so both go through here. + */ +export const canonicalPath = (path: string) => (path.endsWith('/') ? path : `${path}/`);