[object Object]

← back to Watches

Add /api 404 guard before SPA catch-all

6aff506b9a815bf384f936b8157bf44f7db7dfee · 2026-05-19 21:38:29 -0700 · Steve Abrams

Unknown /api/* paths were being swallowed by the app.get('*') fallback
that serves dist/index.html, so a typo'd API URL returned the React shell
(200 with HTML) instead of a proper 404. JSON 404 makes API misuse
detectable on the client + in logs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit 6aff506b9a815bf384f936b8157bf44f7db7dfee
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue May 19 21:38:29 2026 -0700

    Add /api 404 guard before SPA catch-all
    
    Unknown /api/* paths were being swallowed by the app.get('*') fallback
    that serves dist/index.html, so a typo'd API URL returned the React shell
    (200 with HTML) instead of a proper 404. JSON 404 makes API misuse
    detectable on the client + in logs.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
 server.js | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/server.js b/server.js
index fd24b17..fb11e4f 100755
--- a/server.js
+++ b/server.js
@@ -1329,6 +1329,11 @@ app.get('/api/docs', (req, res) => {
   res.redirect('/api/docs/swagger');
 });
 
+// 404 guard: unknown /api/* paths must return JSON 404, not the SPA shell
+app.use('/api', (req, res) => {
+  res.status(404).json({ error: 'Not Found', path: req.originalUrl });
+});
+
 // Fallback route - serve React app with SEO-friendly headers
 app.get('*', (req, res) => {
   res.set({

← 253afbe Broaden .gitignore: snapshot leftovers + SQLite WAL/SHM  ·  back to Watches  ·  Add rel=noopener noreferrer + serve /docs static for api-pla 1f77b3d →