diff --git a/src/routes/_library/$libraryId/$version.docs.framework.$framework.{$}[.]md.tsx b/src/routes/_library/$libraryId/$version.docs.framework.$framework.{$}[.]md.tsx index 7d28abad4..98198898f 100644 --- a/src/routes/_library/$libraryId/$version.docs.framework.$framework.{$}[.]md.tsx +++ b/src/routes/_library/$libraryId/$version.docs.framework.$framework.{$}[.]md.tsx @@ -1,6 +1,11 @@ import { findLibrary, getBranch } from '~/libraries' -import { buildDocsMarkdownRedirectHref, loadDocsRoute } from '~/utils/docs' -import { notFound, createFileRoute } from '@tanstack/react-router' +import { + appendPathToDocsHref, + buildDocsMarkdownRedirectHref, + loadDocsRoute, +} from '~/utils/docs' +import { canonicalUrl } from '~/utils/seo' +import { createFileRoute } from '@tanstack/react-router' import { getDocsCacheHeaders } from '~/utils/docs-cache-headers' import { getContentDispositionHeader } from '~/utils/http-response' import { filterFrameworkContent } from '~/utils/markdown/filterFrameworkContent' @@ -31,7 +36,7 @@ export const Route = createFileRoute( const library = findLibrary(libraryId) if (!library) { - throw notFound() + return new Response('Not found', { status: 404 }) } const root = library.docsRoot || 'docs' @@ -41,6 +46,7 @@ export const Route = createFileRoute( const result = await loadDocsRoute({ repo: library.repo, branch, + latestBranch: getBranch(library, 'latest'), docsRoot: root, docsPath: requestedDocsPath, defaultDocs: library.defaultDocs ?? 'overview', @@ -63,7 +69,7 @@ export const Route = createFileRoute( } if (result.type === 'not-found') { - throw notFound() + return new Response('Not found', { status: 404 }) } const doc = result.doc @@ -82,6 +88,16 @@ export const Route = createFileRoute( headers: { ...cacheHeaders, 'Content-Type': 'text/markdown', + Link: `<${canonicalUrl( + appendPathToDocsHref({ + libraryId, + version: + result.latestDocsPath || version === library.latestVersion + ? 'latest' + : version, + docsPath: result.latestDocsPath ?? result.docsPath, + }), + )}>; rel="canonical"`, 'Content-Disposition': getContentDispositionHeader( 'inline', filename, diff --git a/src/routes/_library/$libraryId/$version.docs.{$}[.]md.tsx b/src/routes/_library/$libraryId/$version.docs.{$}[.]md.tsx index 309a89967..06bfe2940 100644 --- a/src/routes/_library/$libraryId/$version.docs.{$}[.]md.tsx +++ b/src/routes/_library/$libraryId/$version.docs.{$}[.]md.tsx @@ -1,6 +1,11 @@ -import { createFileRoute, notFound } from '@tanstack/react-router' +import { createFileRoute } from '@tanstack/react-router' import { findLibrary, getBranch } from '~/libraries' -import { buildDocsMarkdownRedirectHref, loadDocsRoute } from '~/utils/docs' +import { + appendPathToDocsHref, + buildDocsMarkdownRedirectHref, + loadDocsRoute, +} from '~/utils/docs' +import { canonicalUrl } from '~/utils/seo' import { getDocsCacheHeaders } from '~/utils/docs-cache-headers' import { getContentDispositionHeader } from '~/utils/http-response' import { filterFrameworkContent } from '~/utils/markdown/filterFrameworkContent' @@ -27,7 +32,7 @@ export const Route = createFileRoute( const library = findLibrary(libraryId) if (!library) { - throw notFound() + return new Response('Not found', { status: 404 }) } const root = library.docsRoot || 'docs' @@ -36,6 +41,7 @@ export const Route = createFileRoute( const result = await loadDocsRoute({ repo: library.repo, branch, + latestBranch: getBranch(library, 'latest'), docsRoot: root, docsPath, defaultDocs: library.defaultDocs ?? 'overview', @@ -56,7 +62,7 @@ export const Route = createFileRoute( } if (result.type === 'not-found') { - throw notFound() + return new Response('Not found', { status: 404 }) } const doc = result.doc @@ -77,6 +83,16 @@ export const Route = createFileRoute( headers: { ...cacheHeaders, 'Content-Type': 'text/markdown', + Link: `<${canonicalUrl( + appendPathToDocsHref({ + libraryId, + version: + result.latestDocsPath || version === library.latestVersion + ? 'latest' + : version, + docsPath: result.latestDocsPath ?? result.docsPath, + }), + )}>; rel="canonical"`, 'Content-Disposition': getContentDispositionHeader( 'inline', filename,