diff --git a/src/routes/$libraryId/$version.docs.$.tsx b/src/routes/$libraryId/$version.docs.$.tsx index cd94877d..b9017bcd 100644 --- a/src/routes/$libraryId/$version.docs.$.tsx +++ b/src/routes/$libraryId/$version.docs.$.tsx @@ -81,6 +81,7 @@ export const Route = createFileRoute('/$libraryId/$version/docs/$')({ meta: seo({ title: `${loaderData?.title} | ${library.name} Docs`, description: loaderData?.description, + keywords: loaderData?.keywords, image: ogImageUrl(library.id, { title: loaderData?.title, description: loaderData?.description, diff --git a/src/routes/$libraryId/$version.docs.framework.$framework.$.tsx b/src/routes/$libraryId/$version.docs.framework.$framework.$.tsx index 40bba4c4..26f5eee3 100644 --- a/src/routes/$libraryId/$version.docs.framework.$framework.$.tsx +++ b/src/routes/$libraryId/$version.docs.framework.$framework.$.tsx @@ -76,6 +76,7 @@ export const Route = createFileRoute( ? `${ctx.loaderData.title} | ${tail}` : tail, description: ctx.loaderData?.description, + keywords: ctx.loaderData?.keywords, image: ogImageUrl(library.id, { title: ctx.loaderData?.title, description: ctx.loaderData?.description, diff --git a/src/utils/docs.functions.ts b/src/utils/docs.functions.ts index 2b266c7d..b504c9c3 100644 --- a/src/utils/docs.functions.ts +++ b/src/utils/docs.functions.ts @@ -243,7 +243,9 @@ export const fetchDocs = createServerFn({ method: 'GET' }) } const frontMatter = extractFrontMatter(file) - const description = removeMarkdown(frontMatter.excerpt ?? '') + const description = + frontMatter.userDescription ?? removeMarkdown(frontMatter.excerpt ?? '') + const keywords = extractFrontMatterKeywords(frontMatter.data.keywords) const { contentRsc, headings } = await renderMarkdownToRsc( frontMatter.content, ) @@ -255,6 +257,7 @@ export const fetchDocs = createServerFn({ method: 'GET' }) contentRsc, title: frontMatter.data?.title ?? 'Content temporarily unavailable', description, + keywords, frameworks: extractFrameworksFromMarkdown(frontMatter.content), filePath, headings, @@ -270,6 +273,7 @@ export const fetchDocsPage = createServerFn({ method: 'GET' }) return { contentRsc: doc.contentRsc, description: doc.description, + keywords: doc.keywords, filePath: doc.filePath, frontmatter: doc.frontmatter, frameworks: doc.frameworks, @@ -278,6 +282,24 @@ export const fetchDocsPage = createServerFn({ method: 'GET' }) } }) +function extractFrontMatterKeywords(value: unknown): string | undefined { + if (Array.isArray(value)) { + const normalized = value + .filter((item): item is string => typeof item === 'string') + .map((item) => item.trim()) + .filter((item) => item.length > 0) + + return normalized.length > 0 ? normalized.join(', ') : undefined + } + + if (typeof value === 'string') { + const trimmed = value.trim() + return trimmed.length > 0 ? trimmed : undefined + } + + return undefined +} + export const fetchFile = createServerFn({ method: 'GET' }) .inputValidator(repoFileInput) .handler(async ({ data }: { data: RepoFileRequest }) => { diff --git a/src/utils/documents.server.ts b/src/utils/documents.server.ts index 42833b56..5b516f52 100644 --- a/src/utils/documents.server.ts +++ b/src/utils/documents.server.ts @@ -421,12 +421,17 @@ export function extractFrontMatter(content: string) { excerpt: (file: any) => (file.excerpt = createRichExcerpt(file.content)), }) const redirectFrom = normalizeRedirectFrom(result.data.redirect_from) + const userDescription = + typeof result.data.description === 'string' && + result.data.description.trim().length > 0 + ? result.data.description + : undefined return { ...result, data: { ...result.data, - description: createExcerpt(result.content), + description: userDescription ?? createExcerpt(result.content), redirect_from: redirectFrom, redirectFrom, } as { [key: string]: any } & { @@ -434,6 +439,7 @@ export function extractFrontMatter(content: string) { redirect_from?: Array redirectFrom?: Array }, + userDescription, } }