From 259056c5b75f768a0a1fc26ed15598efd333d847 Mon Sep 17 00:00:00 2001 From: kleap-admin Date: Thu, 15 Jan 2026 13:02:37 +0000 Subject: [PATCH] Update next.config.mjs --- next.config.mjs | 196 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) create mode 100644 next.config.mjs diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..3a0ba4f --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,196 @@ +import nextMDX from "@next/mdx"; +import path from "path"; + +/** @type {import('next').NextConfig} */ +const nextConfig = { + // Turbopack configuration + turbopack: { + root: process.cwd(), + // Configure MDX loader for Turbopack + rules: { + '*.mdx': { + loaders: ['@mdx-js/loader'], + as: '*.js', + }, + }, + }, + + experimental: { + // Enable partial prerendering for faster loads + // ppr: true, // Only available in canary + // Optimize bundling + optimizePackageImports: [ + 'lucide-react', + 'react-icons', + '@tabler/icons-react', + 'framer-motion', + 'react-hook-form', + '@radix-ui/react-label', + '@radix-ui/react-slot', + ], + }, + + // Suppress hydration warnings globally + reactStrictMode: false, + + // Cross-origin configuration for CodeSandbox iframe compatibility + // Note: allowedDevOrigins is not a real Next.js option + + // Image optimization + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: 'i.pravatar.cc', + }, + { + protocol: 'https', + hostname: 'images.unsplash.com', + }, + { + protocol: 'https', + hostname: '*.supabase.co', + }, + { + protocol: 'https', + hostname: 'www.robot-speed.com', + }, + { + protocol: 'https', + hostname: 'robot-speed.com', + }, + ], + formats: ['image/avif', 'image/webp'], + // Use sharp for better performance + loader: 'default', + dangerouslyAllowSVG: true, + contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;", + }, + + // Page extensions - include .js/.jsx for compatibility + pageExtensions: ["js", "jsx", "ts", "tsx", "mdx"], + + // Performance optimizations - CodeSandbox optimized + poweredByHeader: false, + compress: true, + + // TypeScript configuration + typescript: { + ignoreBuildErrors: false // ✅ Show TypeScript errors + }, + + // Optimize production builds for CodeSandbox + productionBrowserSourceMaps: false, + + // ❌ REMOVED: generateBuildId - causes routes-manifest.json error on Vercel + // ❌ REMOVED: staticPageGenerationTimeout - can cause build issues + + // Compiler optimizations + compiler: { + // Remove console logs in production only + removeConsole: process.env.NODE_ENV === 'production', + // Remove data-testid in production + reactRemoveProperties: process.env.NODE_ENV === 'production' ? { properties: ['^data-testid$'] } : false, + }, + + // Module transpilation for better performance + transpilePackages: ['geist', 'cobe'], + + // Force webpack to resolve @ aliases (in case tsconfig.json is not read) + webpack: (config, { _isServer, webpack }) => { + config.resolve.alias = { + ...config.resolve.alias, + '@': path.resolve('.'), + '@components': path.resolve('./components'), + '@lib': path.resolve('./lib'), + '@constants': path.resolve('./constants'), + '@context': path.resolve('./context'), + }; + + // 🔥 NUCLEAR OPTION: Replace tailwind-cdn-loader with empty module in production + // This BLOCKS the file at webpack level - it CANNOT be imported! + // Detect Vercel OR production build in multiple ways to be 100% sure + const isVercel = process.env.VERCEL === '1' || + process.env.VERCEL === 'true' || + process.env.NEXT_PUBLIC_VERCEL === '1' || + process.env.VERCEL_ENV !== undefined || + process.env.VERCEL_URL !== undefined; + + const isProduction = process.env.NODE_ENV === 'production'; + + // Block CDN on Vercel OR in any production build + if (isVercel || isProduction) { + config.plugins.push( + new webpack.NormalModuleReplacementPlugin( + /tailwind-cdn-loader/, + path.resolve('./components/empty-loader.tsx') + ) + ); + console.log('🚫 [WEBPACK] Blocking tailwind-cdn-loader.tsx - replaced with empty-loader.tsx'); + if (isVercel) { + console.log('🚀 [WEBPACK] Vercel detected - CDN will NOT be used'); + } + if (isProduction) { + console.log('🚀 [WEBPACK] Production build - CDN will NOT be used'); + } + } else { + console.log('🎨 [WEBPACK] Development mode - tailwind-cdn-loader will be active'); + } + + return config; + }, + + // Headers for CodeSandbox iframe compatibility + // Note: NO CORS headers needed - health checks use server-side SDK + async headers() { + return [ + // Caching + iframe headers for all routes + { + source: '/:path*', + headers: [ + // Allow iframe embedding (required for Kleap preview) + { + key: 'X-Frame-Options', + value: 'ALLOWALL', + }, + // No cache for development (see AI changes immediately) + { + key: 'Cache-Control', + value: 'no-store, no-cache, must-revalidate, proxy-revalidate', + }, + { + key: 'Pragma', + value: 'no-cache', + }, + { + key: 'Expires', + value: '0', + }, + ], + }, + // Cache headers for static assets (JS, CSS, images) + // In CodeSandbox dev: NO cache to see AI changes immediately + // On Vercel production: Next.js handles caching with content hashes + { + source: '/_next/static/:path*', + headers: [ + { + key: 'Cache-Control', + // no-cache = browser must revalidate before using cached version + // This ensures fresh CSS/JS after AI edits while still allowing conditional caching + value: 'no-cache, no-store, must-revalidate', + }, + ], + }, + ]; + }, +}; + +const withMDX = nextMDX({ + extension: /\.mdx?$/, + options: { + providerImportSource: '@mdx-js/react', + }, +}); + +export default withMDX(nextConfig); \ No newline at end of file