How do I configure nginx for WordPress REST API in sub-folder?
Asked Answered
L

5

7

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

Linkman answered 8/7, 2019 at 7:21 Comment(12)
Can you show the full config?Stylish
I've seen the rewrite line with the last flag at the end. Maybe that is what is missing?Insulin
Thanks @TarunLalwani I have just tried with adding last and also rearranging the order of the two rewrite rules, but it didn't fix the 404Linkman
@JannieTheunissen, I would like to see the full config to be able to comment on something. Currently, just these two lines don't help meStylish
A gist of the full config coming up. I just need to redact a bunch of things in thereLinkman
@TarunLalwani I added the full configLinkman
Do you need both rewrite rules? Why not just the location /site1/. That should set the pretty permalinks for the whole install, including the wp-json endpoints, no? As opposed to trying to rewrite the root, and a subdirectory.Bottali
@Bottali I agree that logically we shouldn't need both, but I added the specific wp-json one because that route fails. Maybe it is caused by some of the other multi-site rules in the config? I just don't know enough nginx to spot it.Linkman
@JannieTheunissen debug rewrite may helpDistinguish
@JannieTheunissen writing the pretty permalinks should effect the entire install, including the endpoints. That is why your other endpoint call works with the query string, which is the default. I also noticed you have an "$is_args$args" as part of it. This could be fine, but if you just tried "?$args" instead.Bottali
@JannieTheunissen, lets discuss this over the gist so commenting code is easierStylish
@JannieTheunissen did you ever get it to work? Running into the same issue. Odd thing is that I was able to get custom routes working with a couple of different methods: rewrite ^/wordpress/wp-json/(.*?)$ /wordpress/index.php?rest_route=/$1 last; and/or try_files $uri $uri/ /wordpress/index.php?$args /wordpress/index.php?q=$uri&$args; But default routes like wp-json/wp/v2/pages return an empty array.Chromogenic
H
5

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;
}
Halftrack answered 24/2, 2022 at 0:55 Comment(0)
C
2

I was able to resolve it like this:

location /wordpress/ {
  rewrite ^/wordpress/wp-json/(.*?)$ /wordpress/index.php?rest_route=/$1 last;
}
Chromogenic answered 4/10, 2019 at 1:42 Comment(1)
I somehow missed your answer before posting mine - this works for me, +1. I'm leaving my answer as I go into more detail about how/why it works, which might be useful to others. I also think a location that more specifically targets just the URIs we want to modify would be better.Portal
E
1

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;
        }
}
Eveevection answered 13/7, 2019 at 2:57 Comment(9)
Thanks Faham. I tried your solution, but it doesn't work.Linkman
Can you please posts the results by running nginx -c /etc/nginx/nginx.conf -t in your terminal.Eveevection
@JannieTheunissen there should be a site-enabled folder in your /etc/nginx can you check if there is any configuration file there? and if so, add the configurations over in that file.Eveevection
There is two included configurations which I have merged into the gist to get the whole pictureLinkman
I know this is a very stupid question but after pondering for hours on your configuration file I am only left with the dumbest question of all. What is your website permalink setting?Eveevection
Thanks for your effort Faham. The permalink setting is Numeric (see question)Linkman
I thought so, its often the simplest of the things. Can you change your permalink to postname and check again.Eveevection
I tried setting permalinks to postname and I still have the same problem. I saw numerous answers on SO where they suggest setting the permalinks to anything other than the default to resolve getting 404 on WordPress ajax callsLinkman
Numeric permalink are never going to work as the rewrite will only work if pretty permalink are on.Eveevection
J
0

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;
}
Jedda answered 15/5, 2020 at 15:7 Comment(0)
C
0

in WordPress RESTful API handbook, there is a description: We will learn how to register our own routes and endpoints in the following sections.

If you are using non-pretty permalinks, you should pass the REST API route as a query string parameter. The route http://oursite.com/wp-json/ in the example above would hence be http://oursite.com/?rest_route=/.

If you get a 404 error when trying to access http://oursite.com/wp-json/, consider enabling pretty permalinks or try using the rest_route parameter instead.

so, you need to rewrite https://yoursite.com/site1/wp-json/wp/v2/posts to https://yoursite.com/site1/?rest_route=/wp/v2/posts

the correct nginx solution is:

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

please note do not forget "=/"

Clasp answered 18/5 at 8:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.