import("dotenv").then(({ config }) => config({ path: "../../.env" })); import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { withSentryConfig } from "@sentry/nextjs/config"; import ffmpegStaticPath from "ffmpeg-static"; import workflowNext from "workflow/next"; const { withWorkflow } = workflowNext; const packageJson = JSON.parse( fs.readFileSync(path.resolve("./package.json"), "utf8"), ); const { version } = packageJson; const appDirectory = fileURLToPath(new URL(".", import.meta.url)); const ffmpegTracingIncludes = ffmpegStaticPath ? [ path .relative(appDirectory, fs.realpathSync(ffmpegStaticPath)) .split(path.sep) .join("/"), ] : []; const nextConfig = { outputFileTracingRoot: path.resolve(appDirectory, "../.."), reactStrictMode: true, serverExternalPackages: ["ffmpeg-static", "prettier"], outputFileTracingIncludes: { "/.well-known/workflow/v1/step": ffmpegTracingIncludes, "/api/tools/loom-download": ffmpegTracingIncludes, "/api/og": ["./lib/og/fonts/*.ttf", "./lib/og/assets/*.jpg"], "/api/video/og": [ "./lib/og/fonts/*.ttf", "./lib/og/assets/*.jpg", ...ffmpegTracingIncludes, ], "/dashboard/settings/organization/billing": ["./lib/baa/*.pdf"], "/api/settings/billing/baa/download": ["./lib/baa/*.pdf"], }, transpilePackages: [ "@cap/ui", "@cap/utils", "@cap/web-api-contract", "@cap/web-domain", "@cap/env", "@cap/database", "@cap/recorder-core", "next-mdx-remote", ], typescript: { ignoreBuildErrors: true, }, experimental: { optimizePackageImports: [ "@cap/ui", "@cap/utils", "lucide-react", "framer-motion", "motion", "@fortawesome/free-solid-svg-icons", "@fortawesome/free-brands-svg-icons", "@tanstack/react-query", "recharts", "@radix-ui/react-dialog", "@radix-ui/react-dropdown-menu", "@radix-ui/react-popover", "@radix-ui/react-select", "@radix-ui/react-slider", "@radix-ui/react-tooltip", "date-fns", ], turbopackFileSystemCacheForDev: true, }, images: { remotePatterns: [ { protocol: "https", hostname: "l.cap.so", port: "", pathname: "**", }, process.env.NODE_ENV === "development" && { protocol: "http", hostname: "localhost", port: "9000", pathname: "**", }, ].filter(Boolean), }, async headers() { return [ { source: "/(.*)", headers: [ { key: "X-Content-Type-Options", value: "nosniff" }, { key: "X-DNS-Prefetch-Control", value: "off" }, ], }, { source: "/((?!api/auth/).*)", headers: [ { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" }, ], }, ]; }, async rewrites() { return [ { source: "/r/:path*", destination: "https://dub.cap.link/:path*", }, { source: "/api/commercial/:path*", destination: "https://l.cap.so/api/commercial/:path*", }, { source: "/s/:videoId", destination: "/s/:videoId", has: [ { type: "host", value: "(?!cap.so|cap.link).*", }, ], }, { source: "/c/:collectionId", destination: "/c/:collectionId", has: [ { type: "host", value: "(?!cap.so|cap.link).*", }, ], }, ]; }, async redirects() { return [ { source: "/roadmap", destination: "https://capso.notion.site/7aac740edeee49b5a23be901a7cb734e?v=9d4a3bf3d72d488cad9b899ab73116a1", permanent: true, }, { source: "/updates", destination: "/blog", permanent: true, }, { source: "/updates/:slug", destination: "/blog/:slug", permanent: true, }, { source: "/docs/s3-config", destination: "/docs", permanent: true, }, ]; }, env: { appVersion: version, }, compiler: { // Sentry is used for errors only (every tracesSampleRate is 0). These // are the SDK's build flags for that: with them the bundler can drop // the tracing and debug-logging code instead of shipping it unused. define: { __SENTRY_DEBUG__: false, __SENTRY_TRACING__: false, }, }, output: process.env.NEXT_PUBLIC_DOCKER_BUILD === "true" ? "standalone" : undefined, }; export default withSentryConfig(withWorkflow(nextConfig), { org: "cap-s2", project: "cap-web", authToken: process.env.SENTRY_AUTH_TOKEN, telemetry: false, silent: !process.env.CI, sourcemaps: { disable: !process.env.SENTRY_AUTH_TOKEN }, });