How to rewrite Rule in apache for wordpress json API v1 and v2

576 views Asked by At

I'm trying to develop a vuejs frontend site with wordpress as headless CMS.

so far everything is fine, but one thing worries me.

the frontend is served at domain.com/index.html so I renamed the wordpress root document index.php to _index.php. For reading the /wp-json/v2/ API I added

RewriteRule ^wp-json/(.*) /_index.php [L] 

to the apache .htaccess file to redirect the call.

However, if I now also want to call the old json API with ?json=, the

RewriteRule ?json(*) /_index.php [L]   

or

RewriteRule ^?json=(.*) /_index.php [L] 

does not work.

how can I use both APIs, no idea why the rewriteRule doesn't work.

this is how mine looks

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
   RewriteBase /
   RewriteRule ^wp-json/(.*) /_index.php [L]
   #RewriteRule ^?json(*) /_index.php [L]
   RewriteRule ^index\.html$ - [L]
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteRule . /index.html [L]
</IfModule>

by the way: is there a way with the json API V2 to output the pages recursively as Parent/Child tree?

1

There are 1 answers

2
MrWhite On BEST ANSWER

so I renamed the wordpress root document index.php to _index.php

Why? If you are having issues with index.php taking priority when requesting the root directory then reset the DirectoryIndex. For example:

DirectoryIndex index.html

Now, only index.html will be checked for when requesting a directory. (It was probably set to something like DirectoryIndex index.php index.html previously, so index.php would take priority.)

RewriteRule ^?json=(.*) /_index.php [L] 

The RewriteRule pattern matches against the URL-path only, which notably excludes the query string. To match the query string you need to use a separate condition (RewriteCond directive) and check against the QUERY_STRING server variable.

For example:

RewriteCond %{QUERY_STRING} ^json=
RewriteRule ^$ index.php [L]

The regex ^$ ensures that only requests for the document root are matched and not any URL-path.

^json= matches any query string that starts json=. The (.*) part is not required. The QUERY_STRING server variable does not include the ? delimiter itself.

NB: The regex ?json(*) (in your first example) is not valid and you'd expect to get a 500 response (if on Apache), since the regex would fail to compile.

The / prefix on the substitution string is not required and should be avoided. (This now makes use of the RewriteBase directive - which isn't actually required here anyway.)

So, in summary, it would look like this, with a few minor tweaks:

# Limit the directory index to "index.html" only
DirectoryIndex index.html

RewriteEngine On

# Pass Authorization header to backend on CGI
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

# Stop early if the front-controllers are already reached
RewriteRule ^index\.(html|php)$ - [L]

# WordPress API
RewriteRule ^wp-json/ index.php [L]
RewriteCond %{QUERY_STRING} ^json=
RewriteRule ^$ index.php [L]

# VueJS
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]