Add query string to url and display it as normal url part /folder/

There are a few points to share because I could foresee that the comment will be very long and I post some suggestion here for reference and hopefully could fix it up.

1st point about the rewrite

$newrules['/(\d*)$'] = 'index.php?city=$matches[1]';

I guess you expect to use a url like https://example.com/new_york/ to the path so city will take up new_york like city=new_york.
However, the rule (\d*) which expect to screen out only digits so character other than 0-9 will be ignored.

Just guessing that it would be ([^/]+)

  • ([^/]+) excluding slash “https://wordpress.stackexchange.com/”, + match any characters 1 to unlimited times
  • () means for capturing group
$newrules['([^/]+)/?$'] = 'index.php?city=$matches[1]';

Please try the regex in this tool
(the tool requires escape of / => written as \/, in php code, it is not necessary in your case)

2nd point about the priority

The rewrite_rules_array is used so the rule above will be added to the end (or near end if there is any other plugins doing the same) of the rule. The rewrite rule is matching sequentially. So, there is chance that the 404 is being determined before the rule is being matched with similar patterns.

The rule could be put in higher priority by a number of ways such as putting in other earlier rule filters or using add_rewrite_rule() with top attribute to make it matching in higher priority. In other words, the possibility of this rule is being matched first is heightened and might result in other undesired effect. So a thorough test to match your needs is necessary. Please expect testing and adjustment to be made before it comes to satisfaction.

Please refer to docs for different filters:

function wpdocs_insert_rewrite_rules( $rules ) {

    $newrules = array();
    $newrules['([^/]+)/?$'] = 'index.php?city=$matches[1]';
    return $newrules + $rules;
}
add_filter( 'TRY_CHANGING_FILER_HERE_IF_LOADING_PRIORITY_MATTERS','wpdocs_insert_rewrite_rules' );

An alternative way to using the above filters using add_rewrite_rule()

add_action('init', 'ws366689_insert_rewrite_rules' );
function ws366689_insert_rewrite_rules() {
        add_rewrite_rule('([^/]+)/?$', 'index.php?city=$matches[1]', 'top');
}

about the writing format

Just a personal opinion that you could use the format shown in the docs to write the array for simplicity and clarity.

function wpdocs_insert_query_vars( $vars ) {

    $vars[] = 'city';
    return $vars;

}
add_filter( 'query_vars','wpdocs_insert_query_vars' );

The rules inside wpdocs_flush_rules() is also needed to be updated.