Skip to content

fix: exclude API paths from SPA catch-all route - #728

Closed
bbrands02 wants to merge 2 commits into
developmentfrom
fix/spa-catchall-exclude-api-routes
Closed

fix: exclude API paths from SPA catch-all route#728
bbrands02 wants to merge 2 commits into
developmentfrom
fix/spa-catchall-exclude-api-routes

Conversation

@bbrands02

@bbrands02 bbrands02 commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Commit 45644173 (2026-03-16, "feat: Enrich 3 specs, add prometheus metrics") introduced a SPA catch-all route /{path} with requirement .+ for the first time. Before that, every frontend route was explicitly registered as a ui#* route — there was no catch-all, and the API worked correctly. The catch-all was broken from the moment it was added: .+ matches every GET path including /api/…, so any API GET request without a more specific route registered above it was handled by the Vue app controller and returned HTML instead of JSON.

Changed the regex to (?!api(?:/|$)).+ so only non-API paths fall through to the SPA. Requests to /api/* now resolve to their resource controllers as intended.

The leading ^ was intentionally omitted from the requirement: Symfony embeds parameter requirements verbatim inside named capture groups in the compiled route regex, so a ^ inside the group would assert start-of-string from a mid-URL position and never match — disabling the catch-all entirely and causing SPA deep links to 404. The negative lookahead anchors implicitly at the start of the parameter value without it.

Test plan

  • GET any /api/… endpoint — verify JSON is returned, not HTML
  • Navigate to a SPA deep link directly in the browser (e.g. /sources/123) — verify the Vue app loads correctly
  • Navigate between frontend routes in the app — verify client-side routing still works
  • Verify no existing API routes are broken

🤖 Generated with Claude Code

bbrands02 and others added 2 commits April 24, 2026 12:19
The catch-all regex '.+' matched every GET path including /api/...,
causing all API GET requests without a more specific route to be served
by the Vue app controller and return HTML instead of JSON.

Narrow the regex to '^(?!api(?:/|$)).+' so only non-API paths fall
through to the SPA, while /api/* routes resolve to their resource
controllers as intended.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…kage

Symfony embeds parameter requirements verbatim inside named capture groups
in the compiled route regex. A leading ^ inside a group asserts start-of-
string, which is never true mid-URL, so the catch-all matched nothing and
SPA deep links returned 404.

The negative lookahead anchors implicitly at the start of the parameter
value without needing ^.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@WilcoLouwerse WilcoLouwerse left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers found. The negative lookahead correctly excludes all /api/... paths from the SPA catch-all while leaving all explicit frontend routes intact; CI failures appear pre-existing and unrelated to this routing-only change.

@bbrands02 bbrands02 closed this May 15, 2026
@bbrands02
bbrands02 deleted the fix/spa-catchall-exclude-api-routes branch May 15, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants