docs(plugins): version breaking API guides (#4245)

Keep stable v0.7 guidance available while the client-entry layout is previewed for v0.8. Existing reference and migration URLs redirect to the release that owns their content.
This commit is contained in:
Mohamed Boudra
2026-09-02 23:45:23 +02:00
committed by GitHub
parent ce07732d62
commit 20ecdee72d
15 changed files with 1585 additions and 274 deletions
+11
View File
@@ -157,6 +157,17 @@ export function getDoc(slug: string): Doc | undefined {
return getDocs().find((d) => d.slug === slug);
}
const legacyPluginDocRedirects: Readonly<Record<string, string>> = {
"/docs/plugins/reference": "/docs/plugins/v0.7/reference",
"/docs/plugins/reference.md": "/docs/plugins/v0.7/reference.md",
"/docs/plugins/migration": "/docs/plugins/v0.8/migration",
"/docs/plugins/migration.md": "/docs/plugins/v0.8/migration.md",
};
export function getLegacyDocsRedirect(pathname: string): string | undefined {
return legacyPluginDocRedirects[pathname];
}
function formatLabel(segment: string): string {
return segment.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
}
@@ -0,0 +1,43 @@
import { describe, expect, it } from "vitest";
import { buildDocsNavTree, getDocs, getLegacyDocsRedirect } from "./docs";
describe("versioned plugin documentation", () => {
it("keeps current and preview releases together in the Plugins navigation", () => {
const plugins = buildDocsNavTree(getDocs()).find(
(node) => node.type === "category" && node.label === "Plugins",
);
expect(plugins).toMatchObject({
type: "category",
children: [
{ type: "page", label: "Versions", href: "/docs/plugins" },
{
type: "group",
label: "Paseo v0.7 — Current",
href: "/docs/plugins/v0.7",
children: [{ type: "page", label: "Reference", href: "/docs/plugins/v0.7/reference" }],
},
{
type: "group",
label: "Paseo v0.8 — Preview",
href: "/docs/plugins/v0.8",
children: [
{ type: "page", label: "Reference", href: "/docs/plugins/v0.8/reference" },
{ type: "page", label: "Migration", href: "/docs/plugins/v0.8/migration" },
],
},
],
});
});
it("keeps existing plugin documentation URLs working", () => {
expect(getLegacyDocsRedirect("/docs/plugins/reference")).toBe("/docs/plugins/v0.7/reference");
expect(getLegacyDocsRedirect("/docs/plugins/reference.md")).toBe(
"/docs/plugins/v0.7/reference.md",
);
expect(getLegacyDocsRedirect("/docs/plugins/migration")).toBe("/docs/plugins/v0.8/migration");
expect(getLegacyDocsRedirect("/docs/plugins/migration.md")).toBe(
"/docs/plugins/v0.8/migration.md",
);
});
});
+7 -1
View File
@@ -1,7 +1,7 @@
import startEntry from "@tanstack/react-start/server-entry";
import { getAndroidVersionCode } from "~/android-version";
import { getCanonicalRedirect } from "~/canonical-url";
import { getDoc } from "~/docs";
import { getDoc, getLegacyDocsRedirect } from "~/docs";
import { getLatestAndroidVersion } from "~/latest-release";
import { buildLlmsTxt } from "~/llms";
@@ -80,6 +80,12 @@ export default {
return Response.redirect(url.toString(), 301);
}
const legacyDocsRedirect = getLegacyDocsRedirect(url.pathname);
if (legacyDocsRedirect) {
url.pathname = legacyDocsRedirect;
return Response.redirect(url.toString(), 301);
}
if (url.pathname === "/llms.txt") {
return markdownResponse(buildLlmsTxt());
}