mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
* Rework docs navigation and move alternatives to top-level pages - Add nested docs nav with categories, collapsible groups, breadcrumbs, and a right-hand page outline with heading slugs. - Move alternatives out of /docs/alternatives into /alternatives/* marketing pages with 301 redirects. - Add github-slugger for heading IDs and require explicit width on SiteShell so new pages can't accidentally pick the narrow prose layout. - Remove the best-practices doc from public-docs. * Make docs content column prose-width
128 lines
3.4 KiB
TypeScript
128 lines
3.4 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { defineConfig, type UserConfig } from "vite";
|
|
import tsConfigPaths from "vite-tsconfig-paths";
|
|
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
import react from "@vitejs/plugin-react";
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
|
|
const repoRoot = path.resolve(__dirname, "../..");
|
|
const siteHost = "https://paseo.sh";
|
|
|
|
function discoverDocsRoutes(): string[] {
|
|
const docsDir = path.join(repoRoot, "public-docs");
|
|
if (!fs.existsSync(docsDir)) return ["/docs"];
|
|
const routes = new Set<string>(["/docs"]);
|
|
const walk = (dir: string) => {
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
walk(full);
|
|
continue;
|
|
}
|
|
if (!entry.name.endsWith(".md")) continue;
|
|
const rel = path
|
|
.relative(docsDir, full)
|
|
.replace(/\.md$/, "")
|
|
.replace(/\/index$/, "");
|
|
if (rel === "index" || rel === "") continue;
|
|
routes.add(`/docs/${rel.split(path.sep).join("/")}`);
|
|
}
|
|
};
|
|
walk(docsDir);
|
|
return [...routes].sort();
|
|
}
|
|
|
|
function discoverAgentRoutes(): string[] {
|
|
const routesDir = path.join(__dirname, "src/routes");
|
|
const reserved = new Set([
|
|
"__root",
|
|
"agents",
|
|
"blog",
|
|
"changelog",
|
|
"cloud",
|
|
"docs",
|
|
"download",
|
|
"index",
|
|
"sponsor",
|
|
"privacy",
|
|
]);
|
|
return fs
|
|
.readdirSync(routesDir, { withFileTypes: true })
|
|
.filter((entry) => entry.isFile() && entry.name.endsWith(".tsx"))
|
|
.map((entry) => entry.name.replace(/\.tsx$/, ""))
|
|
.filter((name) => !reserved.has(name))
|
|
.sort()
|
|
.map((slug) => `/${slug}`);
|
|
}
|
|
|
|
function discoverAlternativeRoutes(): string[] {
|
|
const alternativesDir = path.join(__dirname, "src/routes/alternatives");
|
|
if (!fs.existsSync(alternativesDir)) return [];
|
|
const slugs = fs
|
|
.readdirSync(alternativesDir, { withFileTypes: true })
|
|
.filter((entry) => entry.isFile() && entry.name.endsWith(".tsx"))
|
|
.map((entry) => entry.name.replace(/\.tsx$/, ""))
|
|
.sort();
|
|
return ["/alternatives", ...slugs.map((slug) => `/alternatives/${slug}`)];
|
|
}
|
|
|
|
function discoverBlogRoutes(): string[] {
|
|
const postsDir = path.join(__dirname, "posts");
|
|
if (!fs.existsSync(postsDir)) return ["/blog"];
|
|
const slugs = fs
|
|
.readdirSync(postsDir, { withFileTypes: true })
|
|
.filter((entry) => entry.isFile() && entry.name.endsWith(".md"))
|
|
.map((entry) => entry.name.replace(/\.md$/, ""))
|
|
.sort();
|
|
return ["/blog", ...slugs.map((slug) => `/blog/${slug}`)];
|
|
}
|
|
|
|
const sitemapPages = [
|
|
"/",
|
|
"/agents",
|
|
"/changelog",
|
|
"/cloud",
|
|
"/download",
|
|
"/privacy",
|
|
...discoverAgentRoutes(),
|
|
...discoverAlternativeRoutes(),
|
|
...discoverDocsRoutes(),
|
|
...discoverBlogRoutes(),
|
|
].map((routePath) => ({
|
|
path: routePath,
|
|
}));
|
|
|
|
export default defineConfig((): UserConfig => {
|
|
return {
|
|
server: {
|
|
host: "0.0.0.0",
|
|
port: 8082,
|
|
strictPort: false,
|
|
fs: {
|
|
allow: [repoRoot],
|
|
},
|
|
watch: {
|
|
ignored: ["**/.tanstack/**"],
|
|
},
|
|
},
|
|
plugins: [
|
|
cloudflare({ viteEnvironment: { name: "ssr" } }),
|
|
tsConfigPaths(),
|
|
tanstackStart({
|
|
router: {
|
|
quoteStyle: "double",
|
|
semicolons: true,
|
|
},
|
|
pages: sitemapPages,
|
|
sitemap: {
|
|
host: siteHost,
|
|
},
|
|
}),
|
|
react(),
|
|
tailwindcss(),
|
|
],
|
|
};
|
|
});
|