Making WP REST API call from local React app

I have a React app on my localhost. I’m trying to make a get request to my WordPress backend which is also hosted locally via DevKinsta. At this point, I am simply trying to establish that I can make a get request from my frontend to my backend. I am running into a CORS issue.

This is the error message I’m seeing in my console:
Access to XMLHttpRequest at 'http://rob-test-3.local/wp-json/wp/v2/posts' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Here is my get request:

useEffect(() => {
    const apiUrl = 'http://rob-test-3.local/wp-json/wp/v2/posts';
    
    axios.get(apiUrl)
      .then((res) => {
        console.log('test')
        
      })
      .catch(error => {
        
      })
  }, []);

I have tried using a plugin called LH Multisite CORS which is supposed to work out of the box, but it did not.

I have also tried altering my functions.php file to allow requests from other domains with the following code:

function initCors( $value ) {
  $origin_url = '*';

  // Check if production environment or not
  if (ENVIRONMENT === 'production') {
    $origin_url = 'https://linguinecode.com';
  }

  header( 'Access-Control-Allow-Origin: ' . $origin_url );
  header( 'Access-Control-Allow-Methods: GET' );
  header( 'Access-Control-Allow-Credentials: true' );
  return $value;
}


add_action( 'rest_api_init', function() {

	remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );

	add_filter( 'rest_pre_serve_request', initCors);
}, 15 );

So far I have been unable to resolve this CORS issue. Can someone tell me where I’m going wrong? Please let me know if you need more info. Thank you.

Hello @Damon and welcome to DevKinsta community!
One thing that I would definitely try is to add the header via Nginx. Open the .conf file of your site that is located in /DevKinsta/nginx_sites/ and before the last } sign add one of the following (depending on if you wish to add the header for a specific domain or for all):

add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Origin "http://localhost:3000";

Once done, be sure to restart the Nginx Docker container by clicking the three dots menu and then Restart as in the picture below:

You should then be able to see the header by performing a curl command to your domain in your terminal:

curl -IkL " http://rob-test-3.local"

That should show something like this:

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 23 Jan 2023 08:24:48 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Link: <http://rob-test-3.local/index.php?rest_route=/>; rel="https://api.w.org/"
Access-Control-Allow-Origin: *

Regards,
Alessandro

Thank you for your reply Alessandro. I have followed your directions and was able to see my header via the curl command:

HTTP/1.1 200 OK Server: nginx Date: Mon, 23 Jan 2023 17:35:51 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Link: <http://rob-test-3.local/index.php?rest_route=/>; rel="https://api.w.org/" Access-Control-Allow-Origin: *

However I’m still getting the exact same error message. Can you think of anything else I could try?

Hey @Damon, can you please share a screenshot of the current error (just wanted to be sure that the CORS message hasn’t changed) and also a screenshot of what curl returns with this command:

curl -IkL "http://rob-test-3.local/wp-json/wp/v2/posts"

If the header on that specific page is not there, it might be due to the status that it returns and you might need to add “always” to the Nginx line that has been added.

Regards,
Alessandro

Here is the error message. I’ve included all the console messages that appear upon page load:

Screen Shot 2023-01-23 at 1.04.31 PM

Here is the result when entering curl -IkL "http://rob-test-3.local/wp-json/wp/v2/posts". I can only upload one image apparently so I’ve had to copy paste:

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 23 Jan 2023 21:06:16 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Redirect-By: WordPress
Location: http://rob-test-3.local/wp-json/wp/v2/posts/
Access-Control-Allow-Origin: *

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 23 Jan 2023 21:06:16 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Link: <http://rob-test-3.local/index.php?rest_route=/>; rel="https://api.w.org/"
Access-Control-Allow-Origin: * 

Please let me know if you need anything else. I appreciate your help.

That’s very odd, the header is definitely there :thinking:, I see that Wordpress is adding a trailing slash, do you get the same error if you change your get request from

const apiUrl = 'http://rob-test-3.local/wp-json/wp/v2/posts';

to

const apiUrl = 'http://rob-test-3.local/wp-json/wp/v2/posts/';

Regards,
Alessandro

I have added the forward slash to apiUrl variable and I’m still getting the same error message:

useEffect(() => {
    const apiUrl = 'http://rob-test-3.local/wp-json/wp/v2/posts/';
    console.log(apiUrl)
    
    axios.get(apiUrl)
      .then((res) => {
        console.log('test')
        
      })
      .catch(error => {
        
      })
  }, []);

Screen Shot 2023-01-23 at 1.57.21 PM

Looks like this time a 500 error got recorded too, can you please replace the Nginx line we added with this?

add_header Access-Control-Allow-Origin "*" always;

And restart Nginx like we did before

Regards,
Alessandro

Sorry I forgot to add “always” like you initially instructred.

I’ve added it to my .conf file. I’m no longer getting the CORS error.

However, I’m still not able to GET the posts.

Here is my React code:

useEffect(() => {
    const apiUrl = 'http://rob-test-3.local/wp-json/wp/v2/posts/';
    
    axios.get(apiUrl)
      .then((res) => {
        console.log(res)
        
      })
      .catch(error => {
        console.log('error', error)
      })
  }, []);

Here is the error I’m getting now:

Screen Shot 2023-01-24 at 11.08.25 AM

Site appears to be running.

Any ideas why I can’t console.log my res?

Hello @Damon :wave:

Thank you for your reply and update :slight_smile:
Glad to see that you’re no longer getting the CORS error (after the “always” is added to the add_header line in your NGINX conf file, as suggested by my colleague @Alessandro above).

As I can understand the issue now is that you’re still not able to GET the posts from that local URL:
http://rob-test-3.local/wp-json/wp/v2/posts/ (and it’s showing 500 Internal Server Error, as shown on your screenshot).
I’m still unsure if the 500 error in question is coming from the rob-test-3.local site or from the React app itself.
Do you see any recent 500 error message logged in the rob-test-3_error.log file perhaps, and it would tell more information/details in there? (the site’s error log file should be located inside the ~/DevKinsta/logs/ subfolder)

Regarding your question:

Any ideas why I can’t console.log my res?

Please note that we’re not web developers/programmers (I myself not so familiar and have no experiences with React scripts/codes :sweat_smile: ) and, so we can’t really tell exactly why you can’t do that console.log of your res / not working as expected - and this does not seem to be DevKinsta application related issue/scope.

Maybe you may want to please check this Handling Errors | Axios Docs (I can’t tell much though if that would help to solve the console.log error thing, but you can take a look and give it a try). If it’s still not working, we would suggest to consult/check with someone (programmer) that has more experiences with React apps.

Cheers,
Agus

Thank you for your reply Agus. I appreciate your suggestions. I’ll try taking a look at my error logs.

You’re most welcome Damon! :slight_smile:
Alright sounds good, please take your time!

Cheers,
Agus