/** @type {import('next').NextConfig} */ // v2 const nextConfig = { skipTrailingSlashRedirect: true, experimental: { proxyTimeout: 120000, // 2 minutes for long-running workout generation }, images: { remotePatterns: [ { protocol: "http", hostname: "localhost", port: "8000", }, { protocol: "http", hostname: "0.0.0.0", port: "8000", }, ], }, async rewrites() { const djangoUrl = process.env.DJANGO_INTERNAL_URL || "http://localhost:8000"; // Prefixes that have NO conflicting Next.js page routes const safePrefixes = [ "media", "registered_user", "exercise", "muscle", "equipment", "generator", "videos", "admin", "static", ]; const rules = safePrefixes.flatMap((prefix) => [ { source: `/${prefix}/:path*/`, destination: `${djangoUrl}/${prefix}/:path*/`, }, { source: `/${prefix}/:path*`, destination: `${djangoUrl}/${prefix}/:path*/`, }, ]); // "workout" conflicts with Next.js page route /workout/[workoutId], // so only rewrite specific Django sub-paths (not bare /workout/). const workoutApiPaths = [ "all", "complete", "completed", "create", "planned_workouts", "plan_workout", "add_from_files", ]; for (const sub of workoutApiPaths) { rules.push( { source: `/workout/${sub}/`, destination: `${djangoUrl}/workout/${sub}/` }, { source: `/workout/${sub}`, destination: `${djangoUrl}/workout/${sub}/` }, ); } // /workout//details/ — the segment followed by "details" rules.push( { source: "/workout/:id/details/", destination: `${djangoUrl}/workout/:id/details/` }, { source: "/workout/:id/details", destination: `${djangoUrl}/workout/:id/details/` }, ); return rules; }, }; export default nextConfig;