Comments Form Collection Posting in NextJS

default discord avatar
valakas
6 months ago
24

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

  • discord user avatar
    jesschow
    Payload Team
    6 months ago

    Hey @valakas - have you checked out our form builder plugin? it is really simple to integrate

    https://github.com/payloadcms/plugin-form-builder

    and here is an example repo

    https://github.com/payloadcms/payload/tree/master/examples/form-builder
  • default discord avatar
    valakas
    6 months ago

    Yeah, 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.tsx

    but found it quite hard to understand

  • discord user avatar
    jesschow
    Payload Team
    6 months ago

    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#form

    All 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
  • default discord avatar
    valakas
    6 months ago

    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

  • default discord avatar
    jarrod69420
    6 months ago

    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).

  • default discord avatar
    valakas
    6 months ago

    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?

  • discord user avatar
    jesschow
    Payload Team
    6 months ago

    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();
  • default discord avatar
    valakas
    6 months ago

    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),
  • default discord avatar
    jarrod69420
    6 months ago

    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

  • default discord avatar
    valakas
    6 months ago

    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

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.