I have setup a comments collection and used a many to relation with posts which is working fine in the backend and on the front end.
I now need a form to allow a user to post a comment.
I'm looking for some advice on building a simple form that submits a comment and links with the associated post
Hey @valakas - have you checked out our form builder plugin? it is really simple to integrate
https://github.com/payloadcms/plugin-form-builderand here is an example repo
https://github.com/payloadcms/payload/tree/master/examples/form-builderYeah, I saw that originally but was under the impression that it wouldn't really work for a comments solution.
I was trying to use this to create a simple form submission -
https://github.com/payloadcms/form-builder-example-website/blob/main/components/Blocks/Form/index.tsxbut found it quite hard to understand
Okay I went back and read the initial discussion in the general channel - makes much more sense what you're trying to do here now!
The form-builder might not be a helpful example because what you need is more simple - you will find some good examples of basic forms online:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formAll you need is a form with a single input field, and on submit you can add a function using the local or REST API to create a new document in the Comments collection. Something like this...
import React from 'react'
import payload from "payload";
const handleSubmit = async event => {
try {
await payload.create({
collection: 'comments',
data: {
comment: event.target.comment.value
// NOTE: you will need to pass the post id here so that the comment is associated with the post
// post: post._id
}
})
} catch (err) {
console.log(err)
}
alert(`Thanks for leaving a comment!`)
}
const CommentForm: React.FC = () => {
return (
<form onSubmit={handleSubmit}>
<label>Leave a comment</label>
<input type="text" name="comment" />
<button type="submit">Submit</button>
</form>
)
}
export default CommentForm
Thanks a lot that’s great will give it another shot!
For anyone coming across this, heres a link to the payload local api docs -
https://payloadcms.com/docs/local-api/overview#collections
Any idea why when I import payload, i get errors relating to
error - ./node_modules/@swc/core-darwin-arm64/swc.darwin-arm64.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
I'm using the ecommerce template
Are you attempting to use
payload
on the client? or on the server? The local api is server only, and cannot be used on the client (react code).
This is on my front end. I have a backend running (payload) and front end running (nextjs) both using the templates provided.
Does that mean I need a different solution for a "comments" form on the next js front end?
Ah my apologies, Jarrod is right you can't use the local API on the frontend.
This approach will still work, just swap out the local API request with a REST API request.
In the example above, replace the entire
await payload.create({....})
with something like this:
const req = await fetch('[your-cms-url]/api/comments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
comment: event.target.comment.value,
// post: post id here,
})
})
const res = await req.json();
Thanks for the speedy responses, I'll give it another go!!!
Not sure if i have some sort of cors issue now
Here is my code
import React from 'react'
// import classes from './index.module.scss'
export const CommentForm: React.FC = () => {
const handleSubmit = async event => {
event.preventDefault();
try {
const req = await fetch('http://localhost:8000/api/comments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
comment: event.target.comment.value,
// post: post id here,
})
})
const res = await req.json();
console.log(res);
} catch (err) {
console.log(err)
}
alert(`Thanks for leaving a comment!`)
}
return (
<form onSubmit={handleSubmit}>
<label>Leave a comment</label>
<input type="text" name="comment" />
<button type="submit">Submit</button>
</form>
)
}
but I get an
[09:15:48] ERROR (payload): Forbidden: You are not allowed to perform this action.
errorr
These are defined in payload-config
cors: ['https://checkout.stripe.com', process.env.PAYLOAD_PUBLIC_SITE_URL].filter(Boolean),
csrf: ['https://checkout.stripe.com', process.env.PAYLOAD_PUBLIC_SITE_URL].filter(Boolean),
Are you logged in on the frontend? You’ll need to pass
credentials: true
inside your fetch options object if so.
The underlying issue is the access control on the comments collection preventing you from posting a comment
Thanks for that, adding
credentials: 'include'
to the fetch options worked
Pointing out the access control makes sense too something I will need to adjust
I say it works... I get the message
Comment successfully created
but theres nothing in the backend
event.preventDefault();
has been removed too
Right the issue must be to do with it being set as a draft. Adding
_status: 'published'
inside the body has made them start appearing
Star
Discord
online
Get help straight from the Payload team with an Enterprise License.