From f03c7ed54686b4a6e04b6f01438a4a10702cff75 Mon Sep 17 00:00:00 2001 From: Parithosh-Varma Date: Tue, 29 Sep 2026 12:49:37 +0530 Subject: [PATCH] SEO: landing meta, OG, JSON-LD, robots + sitemap --- scripts/export-tools-ui.ts | 5 +++ src/admin/pages.ts | 29 ++++++++++++++++- src/admin/seo.ts | 67 ++++++++++++++++++++++++++++++++++++++ src/server.ts | 12 +++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/admin/seo.ts diff --git a/scripts/export-tools-ui.ts b/scripts/export-tools-ui.ts index ed21521..dafbd5a 100644 --- a/scripts/export-tools-ui.ts +++ b/scripts/export-tools-ui.ts @@ -12,6 +12,7 @@ import fs from "node:fs"; import path from "node:path"; import { page, keysPage, poolsPage, analyticsPage, historyPage, playgroundPage, providerPage } from "../src/admin/pages.js"; +import { robotsTxt, sitemapXml } from "../src/admin/seo.js"; const ROOT = process.cwd(); const OUT = path.join(ROOT, "tools-site"); @@ -52,14 +53,18 @@ write("playground/index.html", withShim(playgroundPage())); // _redirects stays as the catch-all for unknown ids. const providerShell = withShim(providerPage()); write("provider/index.html", providerShell); +let providerIds: string[] = []; try { const registry = JSON.parse(fs.readFileSync(path.join(ROOT, "data", "providers.json"), "utf8")) as { id?: string }[]; const ids = [...new Set(registry.map((p) => p.id).filter((id): id is string => typeof id === "string" && /^[a-z0-9-]+$/.test(id)))]; + providerIds = ids; for (const id of ids) write(`provider/${id}/index.html`, providerShell); console.log(`provider routes: ${ids.length}`); } catch (e) { console.warn("provider pre-render skipped:", (e as Error).message); } +write("robots.txt", robotsTxt()); +write("sitemap.xml", sitemapXml(providerIds)); fs.copyFileSync(SHIM, path.join(OUT, "api-base.js")); fs.copyFileSync(path.join(ROOT, "src", "logo.png"), path.join(OUT, "logo.png")); diff --git a/src/admin/pages.ts b/src/admin/pages.ts index da5ae9b..74a481a 100644 --- a/src/admin/pages.ts +++ b/src/admin/pages.ts @@ -1,4 +1,5 @@ import { LOGO_V, DOCS_URL, ICONS } from "./branding.js"; +import { HOME_HEAD_EXTRA, SEO_TITLE, subPageHead } from "./seo.js"; import { ADAPTERS } from "../playground/adapters.js"; import { shellCss, shellNav, shellJs, sharedHeader, sharedLayoutCss } from "./shell.js"; import { tokensCss } from "./tokens.js"; @@ -130,7 +131,8 @@ export const page = ` -pool-anything +${SEO_TITLE} +${HOME_HEAD_EXTRA}