e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
208 lines
5.2 KiB
TypeScript
208 lines
5.2 KiB
TypeScript
import { createMDX } from "fumadocs-mdx/next";
|
|
import { withAui } from "@assistant-ui/next";
|
|
import type { NextConfig } from "next";
|
|
|
|
const isDev = process.env.NODE_ENV === "development";
|
|
|
|
const deployEnv = process.env.VERCEL_ENV ?? process.env.NODE_ENV;
|
|
const faviconVariant =
|
|
deployEnv === "preview" || deployEnv === "development"
|
|
? deployEnv
|
|
: undefined;
|
|
|
|
// Browsers prefer the app-router icon <link> tags (icon.svg, icon0.svg,
|
|
// icon1.png) over /favicon.ico, so every icon route must be rewritten for the
|
|
// environment favicon to actually show in the tab.
|
|
const faviconRewrites = faviconVariant
|
|
? [
|
|
{
|
|
source: "/favicon.ico",
|
|
destination: `/favicon.${faviconVariant}.ico`,
|
|
},
|
|
{
|
|
source: "/icon.svg",
|
|
destination: `/favicon.${faviconVariant}.svg`,
|
|
},
|
|
{
|
|
source: "/icon0.svg",
|
|
destination: `/favicon.${faviconVariant}.svg`,
|
|
},
|
|
{
|
|
source: "/icon1.png",
|
|
destination: `/favicon.${faviconVariant}.png`,
|
|
},
|
|
]
|
|
: [];
|
|
|
|
// The playground AI Builder renders same-origin preview routes inside an iframe.
|
|
// Keep frame ancestors self-only so external sites still cannot embed docs pages.
|
|
const cspHeader = `
|
|
default-src 'self';
|
|
connect-src *;
|
|
frame-src * blob:;
|
|
script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval'${isDev ? " 'unsafe-eval'" : ""};
|
|
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
|
|
img-src * blob: data:;
|
|
font-src 'self' https://fonts.gstatic.com data:;
|
|
object-src 'none';
|
|
base-uri 'self';
|
|
form-action 'self';
|
|
frame-ancestors 'self';
|
|
upgrade-insecure-requests;
|
|
`;
|
|
|
|
const config: NextConfig = {
|
|
transpilePackages: ["@assistant-ui/ui", "shiki"],
|
|
serverExternalPackages: ["just-bash"],
|
|
skipTrailingSlashRedirect: true,
|
|
headers: async () => [
|
|
{
|
|
source: "/(.*)",
|
|
headers: [
|
|
{
|
|
key: "Content-Security-Policy",
|
|
value: cspHeader.replace(/\n/g, ""),
|
|
},
|
|
],
|
|
},
|
|
],
|
|
redirects: async () => [
|
|
{
|
|
source: "/docs/runtimes/ai-sdk/v6",
|
|
destination: "/docs/runtimes/ai-sdk/v6-legacy",
|
|
permanent: true,
|
|
},
|
|
],
|
|
rewrites: async () => ({
|
|
beforeFiles: [
|
|
...faviconRewrites,
|
|
{
|
|
source: "/mcp",
|
|
destination: "/api/mcp",
|
|
},
|
|
{
|
|
source: "/.well-known/mcp",
|
|
destination: "/api/mcp",
|
|
},
|
|
{
|
|
source: "/docs/mcp",
|
|
destination: "/api/mcp",
|
|
},
|
|
{
|
|
source: "/docs/.well-known/mcp",
|
|
destination: "/api/mcp",
|
|
},
|
|
{
|
|
source: "/docs.md",
|
|
destination: "/llms.mdx",
|
|
},
|
|
{
|
|
source: "/docs.mdx",
|
|
destination: "/llms.mdx",
|
|
},
|
|
{
|
|
source: "/docs/:path*.md",
|
|
destination: "/llms.mdx/:path*",
|
|
},
|
|
{
|
|
source: "/docs/:path*.mdx",
|
|
destination: "/llms.mdx/:path*",
|
|
},
|
|
{
|
|
source: "/examples.md",
|
|
destination: "/llms.mdx/examples",
|
|
},
|
|
{
|
|
source: "/examples.mdx",
|
|
destination: "/llms.mdx/examples",
|
|
},
|
|
{
|
|
source: "/examples/:path*.md",
|
|
destination: "/llms.mdx/examples/:path*",
|
|
},
|
|
{
|
|
source: "/examples/:path*.mdx",
|
|
destination: "/llms.mdx/examples/:path*",
|
|
},
|
|
{
|
|
source: "/tap/docs.md",
|
|
destination: "/tap-llms.mdx",
|
|
},
|
|
{
|
|
source: "/tap/docs.mdx",
|
|
destination: "/tap-llms.mdx",
|
|
},
|
|
{
|
|
source: "/tap/docs/:path*.md",
|
|
destination: "/tap-llms.mdx/:path*",
|
|
},
|
|
{
|
|
source: "/tap/docs/:path*.mdx",
|
|
destination: "/tap-llms.mdx/:path*",
|
|
},
|
|
{
|
|
source: "/",
|
|
has: [
|
|
{ type: "header", key: "accept", value: "(?:.*text/markdown.*)" },
|
|
],
|
|
destination: "/llms.txt",
|
|
},
|
|
{
|
|
source: "/pricing",
|
|
has: [
|
|
{ type: "header", key: "accept", value: "(?:.*text/markdown.*)" },
|
|
],
|
|
destination: "/pricing.md",
|
|
},
|
|
{
|
|
source: "/pricing.mdx",
|
|
destination: "/pricing.md",
|
|
},
|
|
{
|
|
source: "/docs/:path*",
|
|
has: [
|
|
{ type: "header", key: "accept", value: "(?:.*text/markdown.*)" },
|
|
],
|
|
destination: "/llms.mdx/:path*",
|
|
},
|
|
{
|
|
source: "/examples/:path*",
|
|
has: [
|
|
{ type: "header", key: "accept", value: "(?:.*text/markdown.*)" },
|
|
],
|
|
destination: "/llms.mdx/examples/:path*",
|
|
},
|
|
{
|
|
source: "/umami/:path*",
|
|
destination: "https://assistant-ui-umami.vercel.app/:path*",
|
|
},
|
|
{
|
|
source: "/blog/:path.md",
|
|
destination: "/blog/llms.md/:path",
|
|
},
|
|
{
|
|
source: "/blog/:path.mdx",
|
|
destination: "/blog/llms.md/:path",
|
|
},
|
|
{
|
|
source: "/ph/static/:path*",
|
|
destination: "https://us-assets.i.posthog.com/static/:path*",
|
|
},
|
|
{
|
|
source: "/ph/:path*",
|
|
destination: "https://us.i.posthog.com/:path*",
|
|
},
|
|
],
|
|
fallback: [
|
|
{
|
|
source: "/registry/:path*",
|
|
destination: "https://ui.shadcn.com/registry/:path*",
|
|
},
|
|
],
|
|
}),
|
|
};
|
|
|
|
const withMDX = createMDX();
|
|
|
|
export default withAui(withMDX(config));
|