How to deal with database pagination when a row in between can be deleted by user action?

Short answer: Remember "where you left off" rather than computing the location.

Long answer: See my blog on why "Pagination via LIMIT and OFFSET is evil": http://mysql.rjweb.org/doc.php/pagination . (You are doing the PHP equivalent of using LIMIT and OFFSET, so the blog applies.)

The url for the [Next] would include the id of the last item on this page, then use WHERE id > $id when building the next page. (Or id of the first item off this page, then WHERE id >= $id. This slight difference has a minor effect when a row is inserted between the two.) Also have this in the SQL: ORDER BY id ASC LIMIT 10. It will fetch only 10 rows, regardless of which page. Without this trick, you are fetching all the rows for all the pages before the current one.

[Prev] page is similar, but with a flag saying to go backwards (ORDER BY id DESC LIMIT 10).

[First] is probably best done by not specifying id; then the code will say "Oh, I should build the first page."

[Last] could include a flag for Last or id=-1 or whatever -- then use something like ORDER BY id DESC LIMIT 10 in the SQL.

Without this technique, a row that is deleted or inserted before the current page causes the list to be shifted off by one item (forward or backward), hence, the user misses (bad?) a row or gets a row duplicated (just annoying).