mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-09-10 19:26:00 +00:00
feat(web): real /about and /docs pages (unique crawlable content)
Addresses the top cross-engine AEO finding — every route previously served the homepage SPA. /about and /docs are now distinct routes with their own server-rendered content and titles. - /about: substantive about page (what LogicSRC is, the standards surface, CommandBoard.run reference impl, GitHub, hire-us) — derived from public positioning, no fabricated team. - /docs + /docs/[slug]: render the repo's docs/*.md (curated public set) via marked, statically generated at build (no runtime fs dependency). - Drop about/docs from the catch-all; add doc URLs to the sitemap. Verified in a running build: /about and /docs serve unique content with distinct titles; /docs/[slug] renders each markdown doc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
6518dfb4a9
commit
fb20fd2e99
8 changed files with 291 additions and 9 deletions
62
apps/logicsrc-web/src/lib/docs.ts
Normal file
62
apps/logicsrc-web/src/lib/docs.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
// Repo-root docs/ (read at build time during static generation, so there is
|
||||
// no runtime filesystem dependency in the deployed image).
|
||||
const DOCS_DIR = resolve(process.cwd(), "../../docs");
|
||||
|
||||
// Curated, public-facing reference docs. Internal notes (roadmap, positioning,
|
||||
// arcade) are intentionally excluded.
|
||||
export const DOC_SLUGS = [
|
||||
"openspec-comparison",
|
||||
"data-model",
|
||||
"cli",
|
||||
"tui",
|
||||
"config",
|
||||
"permissions",
|
||||
"plugins",
|
||||
"credential-sharing",
|
||||
"agent-screening",
|
||||
] as const;
|
||||
|
||||
export type DocSlug = (typeof DOC_SLUGS)[number];
|
||||
|
||||
export function isDocSlug(slug: string): slug is DocSlug {
|
||||
return (DOC_SLUGS as readonly string[]).includes(slug);
|
||||
}
|
||||
|
||||
export function readDoc(slug: string): string | null {
|
||||
if (!isDocSlug(slug)) return null;
|
||||
try {
|
||||
return readFileSync(resolve(DOCS_DIR, `${slug}.md`), "utf8");
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function docTitle(markdown: string, slug: string): string {
|
||||
const h1 = markdown.split("\n").find((line) => line.startsWith("# "));
|
||||
return h1 ? h1.replace(/^#\s+/, "").trim() : slug;
|
||||
}
|
||||
|
||||
export function docExcerpt(markdown: string): string {
|
||||
for (const raw of markdown.split("\n")) {
|
||||
const line = raw.trim();
|
||||
if (line && !line.startsWith("#") && !line.startsWith("```") && !line.startsWith(">")) {
|
||||
return line.replace(/[*_`#>[\]()]/g, "").trim().slice(0, 160);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
export type DocSummary = { slug: DocSlug; title: string; excerpt: string };
|
||||
|
||||
export function listDocs(): DocSummary[] {
|
||||
const out: DocSummary[] = [];
|
||||
for (const slug of DOC_SLUGS) {
|
||||
const md = readDoc(slug);
|
||||
if (!md) continue;
|
||||
out.push({ slug, title: docTitle(md, slug), excerpt: docExcerpt(md) });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue