mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-17 03:38:32 +02:00
* feat(web): add use-cases content pipeline with welcome page (MUL-2349) Wire fumadocs-mdx into apps/web with an independent collection rooted at content/use-cases/. Add the first page at /use-cases/welcome (header + H1 + prose + screenshot + footer) using the about-page visual shell. - source.config.ts + lib/use-cases-source.ts (separate from apps/docs) - features/landing/components/mdx/screenshot.tsx wraps next/image - public/use-cases/welcome/screenshot-1.png placeholder (55KB) - next.config.ts wraps NextConfig with createMDX() - .gitignore + eslint ignore .source/ Co-authored-by: multica-agent <github@multica.ai> * feat(web): bilingual db-boy use case with cookie locale (MUL-2349) Extends the use-cases pipeline into the first real article. - ZH + EN MDX (auto-data-analysis.{zh,en}.mdx) sharing three real screenshots; sensitive fields on db-boy-profile.png (RDS host, DB name, password) are blurred in-place. - Cookie-based locale: /use-cases/<slug> reads multica-locale server-side via lib/use-cases-i18n.ts (mirrors LandingLayout's cookie + Accept-Language fallback). Same URL serves either language; no [lang] segment so all other landing routes stay unchanged. - Frontmatter schema (source.config.ts): z.looseObject with declared hero_image / updated_at (required) / category (optional); a preprocess converts YAML-auto-parsed Date back to a YYYY-MM-DD string. - MDX components factory createMdxComponents(locale) routes the secondary CTA to /docs/zh (ZH) or /docs (EN); internal MDX links use <Link> for SPA nav; full-width and half-width colons both trigger [CTA: ...] / [占位图: ...] markers; 副 and Secondary both work as the secondary CTA prefix. - Index page localizes hero / subtitle / card CTA / metadata; sort fallback uses an epoch placeholder so undefined-order disappears. - Landing header + footer surface use-cases entry in both locales. - Detail route: sticky header, right-rail TOC with anchor jumps, scroll-mt-[100px] on H2/H3 so anchor jumps don't slip under the sticky header. - Drop welcome demo page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(web): resolve code review blockers on use-cases PR - Add `use-cases` to reserved_slugs.json + regenerate TS (P1: prevent future workspace slug collision) - Fix dead links in both MDX files: /features/* → /docs/* (P2) - Remove duplicate brand suffix in page title metadata (nit) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Co-authored-by: multica-agent <github@multica.ai> * fix(web): align usecases locale routing * chore: refresh web mdx lockfile * fix(web): type mdx next config adapter * fix(web): wrap settings route page --------- Co-authored-by: multica-agent <github@multica.ai> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import type { NextConfig } from "next";
|
|
import { config } from "dotenv";
|
|
import { resolve } from "path";
|
|
import { resolveRemoteApiUrl } from "./config/runtime-urls";
|
|
import { createMDX } from "fumadocs-mdx/next";
|
|
|
|
// Load root .env so REMOTE_API_URL is available to next.config.ts
|
|
config({ path: resolve(__dirname, "../../.env") });
|
|
|
|
const remoteApiUrl = resolveRemoteApiUrl(process.env);
|
|
const docsUrl = process.env.DOCS_URL || "http://localhost:4000";
|
|
|
|
// Parse hostnames from CORS_ALLOWED_ORIGINS so that Next.js dev server
|
|
// allows cross-origin HMR / webpack requests (e.g. from Tailscale IPs).
|
|
const allowedDevOrigins = process.env.CORS_ALLOWED_ORIGINS
|
|
? process.env.CORS_ALLOWED_ORIGINS.split(",")
|
|
.map((origin) => {
|
|
try {
|
|
return new URL(origin.trim()).host;
|
|
} catch {
|
|
return origin.trim();
|
|
}
|
|
})
|
|
.filter(Boolean)
|
|
: undefined;
|
|
|
|
const nextConfig: NextConfig = {
|
|
...(process.env.STANDALONE === "true" ? { output: "standalone" as const } : {}),
|
|
transpilePackages: ["@multica/core", "@multica/ui", "@multica/views"],
|
|
...(allowedDevOrigins && allowedDevOrigins.length > 0
|
|
? { allowedDevOrigins }
|
|
: {}),
|
|
images: {
|
|
formats: ["image/avif", "image/webp"],
|
|
qualities: [75, 80, 85],
|
|
},
|
|
async rewrites() {
|
|
return {
|
|
// Run before file-system routes so /docs isn't shadowed by the
|
|
// [workspaceSlug] dynamic segment.
|
|
beforeFiles: [
|
|
{
|
|
source: "/docs",
|
|
destination: `${docsUrl}/docs`,
|
|
},
|
|
{
|
|
source: "/docs/:path*",
|
|
destination: `${docsUrl}/docs/:path*`,
|
|
},
|
|
],
|
|
afterFiles: [
|
|
{
|
|
source: "/api/:path*",
|
|
destination: `${remoteApiUrl}/api/:path*`,
|
|
},
|
|
{
|
|
source: "/ws",
|
|
destination: `${remoteApiUrl}/ws`,
|
|
},
|
|
{
|
|
source: "/auth/:path*",
|
|
destination: `${remoteApiUrl}/auth/:path*`,
|
|
},
|
|
{
|
|
source: "/uploads/:path*",
|
|
destination: `${remoteApiUrl}/uploads/:path*`,
|
|
},
|
|
],
|
|
fallback: [],
|
|
};
|
|
},
|
|
};
|
|
|
|
// fumadocs-mdx@12 is incompatible with Next 16's Turbopack: its loader fails to
|
|
// dynamic-import `.source/source.config.mjs` under the Turbopack Node evaluator
|
|
// (see fumadocs#2658). `dev`/`build` scripts pass `--webpack` to opt out.
|
|
// Drop the flag once fumadocs-mdx ships a Turbopack-compatible loader.
|
|
const withMDX = createMDX() as (config: NextConfig) => NextConfig;
|
|
|
|
export default withMDX(nextConfig);
|