Skip to content

Commit c6e4b80

Browse files
committed
feat(showcase/shell): add 301 redirects from /docs /ag-ui /reference /[framework] to docs.showcase.copilotkit.ai
Shell no longer hosts MDX docs routes — they live on shell-docs (docs.showcase.copilotkit.ai). Add permanent redirects from the legacy shell paths so old URLs and SEO authority carry over to the new host. Framework slugs are enumerated from registry.json at build time (not a :slug* wildcard) so /integrations and /matrix — both still owned by shell — are NOT caught by the redirect. Fixed routes (/docs, /ag-ui, /reference) cover the three other docs catch-alls.
1 parent fc80501 commit c6e4b80

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

showcase/shell/next.config.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,88 @@ function localBackendsEnv(): string {
2020
return JSON.stringify(map);
2121
}
2222

23+
// Read registry to get the list of framework slugs owned by the docs
24+
// shell. Any path whose first segment is a framework slug must 301 to
25+
// docs.showcase.copilotkit.ai. This list is derived at build time so
26+
// the redirect table tracks registry changes automatically — no manual
27+
// sync between next.config.ts and the docs shell's ownership list.
28+
function frameworkSlugs(): string[] {
29+
const registryPath = path.resolve(__dirname, "src", "data", "registry.json");
30+
if (!fs.existsSync(registryPath)) return [];
31+
try {
32+
const registry = JSON.parse(fs.readFileSync(registryPath, "utf-8")) as {
33+
integrations?: { slug: string }[];
34+
};
35+
return (registry.integrations ?? []).map((i) => i.slug);
36+
} catch {
37+
return [];
38+
}
39+
}
40+
41+
const DOCS_HOST = "https://docs.showcase.copilotkit.ai";
42+
2343
const nextConfig: NextConfig = {
2444
env: {
2545
NEXT_PUBLIC_BASE_URL:
2646
process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000",
2747
NEXT_PUBLIC_LOCAL_BACKENDS: localBackendsEnv(),
2848
},
2949
serverExternalPackages: ["@copilotkit/runtime", "@copilotkitnext/runtime"],
50+
async redirects() {
51+
const slugs = frameworkSlugs();
52+
// Fixed docs-route redirects — whole sections (docs, ag-ui, reference)
53+
// now live on docs.showcase.copilotkit.ai. Use 301 (permanent) so
54+
// search engines carry authority over to the new host.
55+
const fixed = [
56+
{
57+
source: "/docs",
58+
destination: `${DOCS_HOST}`,
59+
permanent: true,
60+
},
61+
{
62+
source: "/docs/:path*",
63+
destination: `${DOCS_HOST}/:path*`,
64+
permanent: true,
65+
},
66+
{
67+
source: "/ag-ui",
68+
destination: `${DOCS_HOST}/ag-ui`,
69+
permanent: true,
70+
},
71+
{
72+
source: "/ag-ui/:path*",
73+
destination: `${DOCS_HOST}/ag-ui/:path*`,
74+
permanent: true,
75+
},
76+
{
77+
source: "/reference",
78+
destination: `${DOCS_HOST}/reference`,
79+
permanent: true,
80+
},
81+
{
82+
source: "/reference/:path*",
83+
destination: `${DOCS_HOST}/reference/:path*`,
84+
permanent: true,
85+
},
86+
];
87+
// Framework-scoped routes — /<slug> and /<slug>/... both go to the
88+
// docs host. Enumerated from registry rather than a `:slug*` wildcard
89+
// so we DON'T blanket-redirect /integrations or /matrix (which are
90+
// owned by shell).
91+
const frameworkRedirects = slugs.flatMap((slug) => [
92+
{
93+
source: `/${slug}`,
94+
destination: `${DOCS_HOST}/${slug}`,
95+
permanent: true,
96+
},
97+
{
98+
source: `/${slug}/:path*`,
99+
destination: `${DOCS_HOST}/${slug}/:path*`,
100+
permanent: true,
101+
},
102+
]);
103+
return [...fixed, ...frameworkRedirects];
104+
},
30105
};
31106

32107
export default nextConfig;

0 commit comments

Comments
 (0)