How to post comments using the WordPress REST API
A quick tutorial on how to use the WordPress REST API to post comments asynchronously.
I recently converted my WordPress blog into a headless, Gatsby-powered site, and one of my requirements was to have a working comment form. I knew this was possible using the WordPress REST API but I didn’t find the documentation very helpful and was not able to find any good examples. I decided to document the steps I took to make a working comment form for my blog with the hopes of helping others looking to do a similar thing.
The example in this post uses React JSX, but the code can easily be applied to a regular PHP-based WordPress site that uses vanilla JavaScript.
You can see a quick video of the comment form in action below. Or, you can also try it out by using the comment form at the bottom of this page 😊.
1. Open Inspector’s Network tab
First thing’s first, let’s open up Chrome’s Network tab for debugging. This handy tab will tell us if the comment was submitted properly and about any errors we might get. Other browsers should have a similar tab, but for the purpose of this tutorial I’m going to stick with Chrome.

2. Enable anonymous comments
Before we create the form, we have to enable anonymous comments on your WordPress theme. This is done by enabling the
rest_allow_anonymous_comments hook.
Open your WordPress theme’s functions.php
, and add the following snippet:
add_filter( 'rest_allow_anonymous_comments', '__return_true' );
If you skip this step and try to post a comment using the REST API, you will get a 401: Sorry, you must be logged in to comment.
error.

Shoutout to @websupporter for this tip!
3. Create a form
The next step is to create the comment form. Since I’m using Gatsby, the code example below is in React JSX, but you can convert it to be plain old HTML.
<form>
<input type="hidden" id="postId" value={POST_ID} />
<div>
<label htmlFor="name">Name*</label>
<input id="name" type="text" required />
</div>
<div>
<label htmlFor="email">Email*</label>
<input
id="email"
type="email"
required
/>
</div>
<div>
<label htmlFor="comment">Comment*</label>
<textarea
id="comment"
required
/>
</div>
<input type="submit" value="Post comment!" />
</form>
The form must contain the following information:
- post ID (usually a four digit number, ex:
4583
) - comment author’s name
- comment author’s email
- content for the comment
In my case, I’m passing the post ID as a prop from my template that handles all of the GraphQL queries. If you’re working in PHP, I believe you can use <?php the_ID(); ?>
to get the post ID.
Other details such as the date and IP address are filled out automatically so you shouldn’t need to pass those into the form. For the IP address, you’ll see something like ::1
on your local WordPress instance, but on your production site you should see the actual IP address of the comment author.
4. Create a handler for your form
Add an onSubmit
handler to the <form>
.
<form onSubmit={this.handleSubmit.bind(this)}>
<input type="hidden" id="postId" value={POST_ID} />
<div>
<label htmlFor="name">Name*</label>
<input id="name" type="text" required />
</div>
...
...
Finally, let’s add the code for the handler.
handleSubmit(evt) {
evt.preventDefault();
const [postId, name, email, comment] = evt.target.elements;
const data = JSON.stringify({
post: postId.value,
author_name: name.value,
author_email: email.value,
content: comment.value,
});
// ACTION_URL = "https://your-wordpress-site.com/wp-json/wp/v2/comments"
fetch(ACTION_URL, {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: data,
})
.then((response) => {
if (response.ok === true) {
// Submitted successfully!
}
return response.json();
})
.then((object) => {
// Comment submission failed.
// Output `object.message` to see the error message.
})
.catch(error => console.error('Error:', error));
}
Here’s a quick breakdown of what’s happening:
- Do
preventDefault()
to prevent the form from submitting - De-structure
postId
,name
,email
, andcomment
fromevent.target.elements
- Do a
fetch
to post toACTION_URL
(this is the/wp-json/wp/v2/comments
endpoint of your WordPress blog). - Once we receive the response, check for the value of
response.ok
.- If
true
, the comment was submitted successfully. Otherwise, runresponse.json()
, which returns a promise.
- If
- Once the promise is resolved, we receive an object which gives us all sorts of details about what went wrong. You can output
object.message
to see the message that was returned from WordPress.
That’s it! You should now have a working, basic WordPress comment form that posts comments using the REST API. You can check out the code for the more complete version (including states for buttons, error messages, etc.) here – it may be useful to see it in a React/Gatsby context.
Please leave a comment if you have any questions or advice!
34 Comments
test comment
Testing Comment
ghj
How to validate the input?
Its working?
how can I send comment meta data with this method?using meta object doesn’t work
Hi Abtin, I haven’t tried this with comment metadata at all but I’ll try to look into it in the future.
Thanks for the tutorial! Just wondering, as I am trying to make my own WordPress to React app… how would you make sure users can add POSTS?
And how would we show the CURRENT comments that are already on the website, in the app?
Can you help?
Thankyou worked it
@Lyubo You can create a php class and make the request got through this class, and finally make the class send the request for you
Thank you , its working fine for me
Comment test
test comment
test :D
Test comment
Test Comment
this is a comment
I am really really really really well educated and really really really reach and all women love me!
Headhunter a female with black hair and the model for skins like Snorkel Ops; Spitfire the black male in Fortnite and the model for the Stratus skin
Test Comment
Thanks! Good tutorial
This sounds cool!
Thank you for the tutorial !
Thank you so much for this! I looked all over to resolve the 401 error. This worked like a charm!
Test comment
m,m,
test comment
We are using this solution – thanks!
nice job, missing parent comment id, im using in my case
parent: $(‘#comment_parent’).val()
Hi, nice tutorial :) i am looking for someone who can make a gatsby & wp site for me. could you DM over Twitter or send me an email.
test 2
Thanks for the awesome tutorial.
test
test
test
test
test
test