Rendering Blocks for a Portfolio Website in 2023?

default discord avatar
taun2160
4 months ago
18

Hi. What is the logic of the blocks within the Payload website repo? The Next-custom-server repo contains a component.tsx file for every block, containing the react code. The blocks of the website (a much newer repo, I assume using Nextjs13) doesn't have a component.tsx, only an index.ts config file?

https://github.com/payloadcms/website/tree/main/src/blocks/Content

Have those block components been moved to the components folder at the root of the app? If so, what's the 2023 theory and approach to rendering blocks?



I'd like to create a portfolio website that renders a home page containing Hero Portfolio items of 3 selected items and a Work page containing the Hero Portoflio Items block with a Portoflio Items block below it. I assume I need to create these pages as blocks and then create the pages and add the blocks as layouts for each page, rather than create the pages within my IDE?



This is the theory I've got from looking at the custom-server template for Next:



1. Define a block configuration object using the Block type from the payload/types module. This object defines the fields that are available for the block and how they should be rendered in the admin UI.
2. Define the block component: Create a React component that will render the block on the frontend of the website. This component should receive the values of the fields defined in the block configuration as props.
3. Add the block to the collections and components objects. This will allow the block to be selected and rendered in the Payload admin UI.
4. Add the block to the layout array in the Page collection configuration. This will determine the order in which the blocks are rendered on the page.
The RenderBlocks component receives the layout array as a prop and maps over it to render each block using the corresponding block component.
5. Render the RenderBlocks component: In the page component (...slug.ts), render the RenderBlocks component passing the layout array as a prop. This will render all the blocks in the layout array in the order they were defined.
  • default discord avatar
    paulpopus
    4 months ago

    Yes ^ this is what I'm doing as well



    However this is what I'm doing instead:



    // ContentSerialiser.tsx
    
    import dynamic from 'next/dynamic'
    import { ContentSections } from '@custom-types/content'
    import classes from './ContentSerialiser.module.css'
    
    interface Props {
      content?: Array<ContentSections>
    }
    
    const RenderTextSection = dynamic(() => import('@components/ContentSerialiser/sections/RenderTextSection'))
    
    // all my other sections
    
    export function ContentSerialiser(props: Props) {
      if (!props.content) {
        return null
      }
    
      return (
        <>
          {props.content.map((section, index) => {
            return (
              <section
                key={`${section.__typename}-${index}`}
                className={`${classes.section} ${section.__typename && classes[section.__typename]}`}>
                {(() => {
                  switch (section.__typename) {
                    case 'TextSection':
                      return <RenderTextSection section={section} />
                    default:
                      return null
                  }
                })()}
              </section>
            )
          })}
        </>
      )
    }


    you don't need this

    section

    wrapper and other things...im dynamically importing the Render components, inside some of them I have additional logic before the data goes into the actual re-usable component like ImageBlock or CodeBlock



    the dynamic import i'd say is the more useful part when you can expect to have a larger number of components

  • default discord avatar
    taun2160
    4 months ago

    Interesting, thanks @paulpopus .



    So I absolutely have to take a block approach? Can the user/admin create Portfolio Items, Hero items, blog posts, Home Hero text, About text as collections and I map over the collection(s) I'd like to render to a page that's setup in Nextjs within my IDE within the app folder for dynamic routing? I don't need the user to create new blocks of content, just edit the existing content and have the ability to CRUD portfolio items, Hero portfolio items and blog posts?



    That way I can skip the renderBlock approach and just fetch the data from collections?

  • default discord avatar
    paulpopus
    4 months ago
    So I absolutely have to take a block approach?

    No, it's just usually done this way to provide the maximum flexibility between the needs of the editor and the needs of the developer. Until we get a really sexy rich text editor at least



    I'm confused by what you mean in splitting the items into collections...you can also provide specific

    group

    or just regular fields for each section as well if you want a more fixed editorial experience



    So you don't absolutely

    need

    blocks and the current rich text editor can support you adding images and custom elements into it if you want a one-field-does-all kind of thing..the data being outputted is still in a nice json format you can manipulate as needed



    But using blocks in an array is helpful if you want the editors to have some form of free flow of different types of blocks and you can keep the same logic across landing pages and simple pages where you just limit the available types of blocks

  • default discord avatar
    taun2160
    4 months ago

    I understand that it's great if the editor wants to create a new service and therefore page and insert a block that meets those needs. For my case - I'm supplying a fixed template where the admin can only CRUD content. The styling and layout remains fixed - they can't edit font properties or any of that, for now.



    I'd like to have a collection for each set of content - Hero Content (top 3 portfolio items), Portfolio Items (Eg. Title, description, images, thumbnail image), Blog posts (same as portfolio items fields). Those fields are rendered via React code within Next? This is the first website I'm making so I might be misunderstanding something.



    I'd like to make it as simple as possible for the first one - so just creating collections of JSON and rendering that within components sounds ideal?

  • default discord avatar
    paulpopus
    4 months ago

    Ahh I get it...


    I would do 2 collections:


    - portfolio items


    - blog items



    then do a Global where you can configure the homepage for example, in there you can provide a relationship field if you want them to choose top 3 portfolio items



    Just give them a rich text area or w/e you need, you dont

    need

    to use an array of blocks in which case you likely dont need ^ this renderSections structure



    you would just render the components straight on the page as you get the data



    This is the quickest and simplest option

  • default discord avatar
    taun2160
    4 months ago

    Cool, sounds good, thanks Paul.

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.