From 6ea431bc7524dc761ced987e513eee950a4eef86 Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Sun, 1 Mar 2026 21:27:38 +0000 Subject: [PATCH] Fix SSE routing: exclude text/event-stream requests from API rewrite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit afterFiles ordering was insufficient in Next.js 14 — the catch-all /api/v1/* rewrite still intercepted SSE requests before route handlers. Fix: add a `missing` condition on `Accept: text/event-stream` to the rewrite rule. EventSource always sends this header, so SSE requests now skip the rewrite entirely and are handled by the existing route handlers (app/api/v1/ppt/outlines/stream, presentation/stream, jobs/stream). Normal JSON API requests are unaffected. Co-Authored-By: Claude Sonnet 4.6 --- frontend/next.config.mjs | 44 ++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/frontend/next.config.mjs b/frontend/next.config.mjs index 0d6a706..c4643ef 100644 --- a/frontend/next.config.mjs +++ b/frontend/next.config.mjs @@ -7,29 +7,29 @@ const nextConfig = { // Proxy API and static asset requests to FastAPI backend. - // afterFiles: Next.js checks route handlers first; only falls through to - // these rewrites if no matching app/api/ route handler exists. - // This ensures SSE route handlers (outlines/stream, presentation/stream, etc.) - // are served directly without being intercepted by the catch-all /api/v1/* rewrite. + // + // The /api/v1/* rewrite uses a `missing` condition on the Accept header so + // it does NOT match SSE requests (EventSource always sends Accept: text/event-stream). + // SSE paths have explicit route handlers in app/api/v1/*/stream/[id]/route.ts + // that stream events properly. Normal JSON requests go through the rewrite as before. async rewrites() { - return { - beforeFiles: [], - afterFiles: [ - { - source: '/api/v1/:path*', - destination: `${API_URL}/api/v1/:path*`, - }, - { - source: '/app_data/:path*', - destination: `${API_URL}/app_data/:path*`, - }, - { - source: '/static/:path*', - destination: `${API_URL}/static/:path*`, - }, - ], - fallback: [], - }; + return [ + { + source: '/api/v1/:path*', + missing: [ + { type: 'header', key: 'accept', value: 'text/event-stream' }, + ], + destination: `${API_URL}/api/v1/:path*`, + }, + { + source: '/app_data/:path*', + destination: `${API_URL}/app_data/:path*`, + }, + { + source: '/static/:path*', + destination: `${API_URL}/static/:path*`, + }, + ]; }, images: {