WP Pagination on Posts Search Results Page resulting from AJAX WP Query

I seemingly found a solution, and this is a lot more complicated than I thought. So to be clear again, let’s say I have a page like this:

<header></header>
<main>
  <!-- Posts from query (see question) inserted here -->
  <!-- Pagination Links from query (see question) inserted here -->
</main>
<footer></footer>

To generate the <main> part, I use a function which holds the code of my question, let’s say function A, which returns the content to be inserted into <main> as HTML string. So on page load, I simply insert the returned value of function A into the <main> part.

THEN, I have a button on my page which re-calls function A via wp – ajax, and replaces the content of <main> with the exact same value, by additionally using the s parameter in the WP_Query as described in my question.

The content gets updated successfully, as well as the pagination links do, with one difference: wp-admin/admin-ajax.php?ranum=0.825265473159516 gets added into the URL of each pagination link, the random number probably to avoid cached subpage results. When clicking on one of these pagination links, I get a 400 error, with no request / response data, and a blank page with a 0 appearing as the result. Nothing else useful shown in the network analysis.

I then came across this post. This tells how to add the search string parameter to the URL to be able to use it throughout the updated pagination. I did this, and then edited the search.php template page in the theme to have the same content as the concerned page, by using the $_GET["s"] parameter for function A called in search.php, and it now all worked. The changed code in function A is:

$paginate_args = [
  'base' => home_url( '/%_%' ),
  'format' => 'page/%#%/',
  'current' => max( 1, get_query_var('paged') ),
  'total' => $posts->max_num_pages
];

// $query_string holds the sanitized input of the typed string 
// into the search field

if( $query_string !== "" ) {

  $paginate_args['add_args'] = array( 's' => $query_string );

}

$output .= "<div id=\"post-navigation-links\">".

        paginate_links( $paginate_args ).

        "</div>";

The pagination of the updated page containing search-filtered posts now perfectly works. Interestingly, the link’s structure is now:

https://example.ch/page/3/?s=star&ranum=0.3987907805552596

so the wp-admin/admin-ajax.php part is gone from the link, but we are also loading a different page now (the search page), and not simply making an AJAX request. So this works now, but I have no clue how / if you can make this behaviour work with an AJAX request, and still don’t know what the actual problem was. Of course, it would still be better to find an AJAX solution, to avoid to need to reload the entire page with each pagination, but this even seems to be default behaviour in wp pagination. Maybe you’re better off developing your own pagination scripts, which sets a specific offset and post limit of 8 to each pagination request, or similar..

The problem was may related to the fact that I previously used get_pagenum_link(1) as the base URL for pagination, which is why when called via AJAX, the pagination links hold the AJAX URL part.. Still, when only switching that part with the new home_url( '/%_%' ), when you click on one of the new pagination links, you get to the corresponding page of the initial pagination, loaded on page load; so the only solution seems to be the one I’ve specified in this answer (page re-loads + search page) or custom AJAX scripting, as mentioned.