'How do I configure nginx for WordPress REST API in sub-folder?

I am trying to set up multiple Wordpress sites in sub-folders under our domain (ie not multi-site), but I have difficulty configuring the REST API endpoints. For example, this endpoint works fine:

https://example.com/site1/?rest_route=/wp/v2/posts

But this endpoint gives a 404:

https://example.com/site1/wp-json/wp/v2/posts

I have tried to rewrite the failing url to the working url with these rules in my nginx configuration:

location /site1/wp-json {
    rewrite ^/site1/wp-json(.*)$ /site1/?rest_route=$1;
}

location /site1/ {
   try_files $uri $uri/ /site1/index.php$is_args$args;
}

I can't see any special handling of wp-json in the WordPress docs or the nginx wiki. What am I missing here? The permalinks for the site is set to Numeric (https://example.com/site1/archives/123) if that might play a role.

Update

Gist of the redacted full config file and the config syntax lints okay:

nginx -c /etc/nginx/nginx.conf -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful



Solution 1:[1]

I just hit this too, in WP 5.7. Without pretty permalinks, ie with the "Plain" option like ?p=123, my nginx WP installation uses requests like:

/index.php?rest_route=/wp/v2/users/&who=authors...

And these all work fine.

However if I enable pretty permalinks, eg "Post name", /sample-post/, it starts making requests like:

/wp-json/wp/v2/users/?who=authors...

And these all return a 404. For example, editing or publishing posts fails, and browser devtools shows a string of 404s in this format.

But now we know the pattern that works, a solution is clear - we just need to map the not-working format to the working format:

# Resolves WP Gutenberg 404 issue
location /wp-json {
    rewrite ^/wp-json(.*)$ /index.php?rest_route=$1 last;
}

Solution 2:[2]

I believe that the rewrite directive should be written as shown below:

server {
    location /site1/wp-json
        {
            rewrite ^(/site1/wp-json.*)$ /site1/?rest_route=$1 last;
        }
}

Solution 3:[3]

I was able to resolve it like this:

location /wordpress/ {
  rewrite ^/wordpress/wp-json/(.*?)$ /wordpress/index.php?rest_route=/$1 last;
}

Solution 4:[4]

An easy way if your website pages in the subfolder is already working, just add index.php to the url:

https://site1.com/site2/index.php/wp-json/

If your website pages still doesn't work in the subfolder, add this code to nginx/sites-available/website.conf file too:

location /site2 {
        rewrite ^(/[^/]+)?(/wp-.*) /site2/$2 break;
        rewrite ^/site2/(.*)$ /site2/index.php?q=$1 last;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Faham Shaikh
Solution 3 geochanto
Solution 4 Fellipe Sanches