coolify-full — architecture note

Same routes, same controllers. The delivery mechanism changed underneath them.

84 pages migrated from Blade + Livewire to Inertia.js + React, one page at a time, with both stacks running side by side until each page was fully converted, tested, and verified — never a big-bang rewrite. The request still lands on the same routes/web.php entry and the same controller either way.

Before

Blade + Livewire

Browser
full page GET
Route + Controller
ProjectController::index
Blade view
renders a Livewire component
Livewire runtime
wire:click → AJAX → same Blade template, re-rendered server-side
Response: full HTML document, then server-rendered partials for every interaction
After

Inertia.js + React

Browser
Inertia visit, XHR
Route + Controller
ProjectController::index
Inertia::render()
component name + props, as JSON
React component
renders client-side, pushState — no reload
Response: JSON props on navigation, real DOM diffing for every interaction
84 / 84
pages converted, page by page — both stacks coexisted the whole time
0
new API endpoints written — controllers kept returning props, not a separate JSON API
1
thing that never moved: auth, sessions, and CSRF, unchanged on both sides

Why this shape, not a decoupled SPA: a fully separate API would have meant designing and versioning an entire API surface before migrating even one page. Inertia let each page keep using its existing controller almost unchanged — the trade was giving up independent deployability and a reusable API layer a future non-web client could have consumed.