I did the exact same thing. I made a page with a table that was fully rendered server side. Any change in the display, such as pagination, sorting or filtering would trigger the same PHP code that returned a HTML fragment. The Javascript for that was easy. Just send an AJAX request to the server and replace the <tbody> element with the new content.
The PHP code itself was separated in components which made it easy to share the rendering logic for the initial page and the page used for the AJAX request.
React solves this in a more convenient way, but I am really surprised that we had to wait until 2023 before it happened.