Baby steps - how do I render a rich image and caption to a home page?

default discord avatar
Taun
2 months ago
32

Hi. I'm a web dev noob who's just learned React and a bit of NextJS & Tyepscript who is new to learning dynamic routing and headless CMSs. I'm studying Payload's custom-website-series repo (

https://github.com/payloadcms/custom-website-series

) which is a few levels above me, so I'm struggling to connect the dots and understand the processes involved.



"Each page in Payload CMS is stored as a document in the Payload CMS API, which includes all of the content and layout information that you have defined for that page. When a user visits a page on your site, Next.js uses the getStaticProps function to fetch the content and layout data for that page from the Payload CMS API, and uses that data to generate the HTML for the page."



So do I define the structure and content of the pages by creating blocks and then adding content within those blocks using the Payload admin dashboard?



Then how do I render that data to the website? All I know at this point is that I need to use getStaticProps and Paths to fetch data from PayloadCMS.



I'd like to create the most simple page using PayloadCMS and Nextjs - a rich image and caption text.



What is the process? Eg.



1. Define a collection, such as Media that contains the fields for the image and rich text?


2. Create a block that packages the image and text?


3. Render the block within a page?

  • default discord avatar
    thisisnotchris
    2 months ago

    Hey @Taun, I think you've got the right idea. You'll notice that when creating an item in a collection, the JSON representation of that item becomes available to your API.



    That JSON has all the data needed to render your content



    Though, most people will fetch the data and then display it

  • default discord avatar
    Taun
    2 months ago

    Great, thanks NotChris.



    Hi @thisisnotchris . If you've got a few min I'll appreciate your help -



    I'd like to render a block called CoverBlockComponent.ts, I assume to a page that uses getserverprops to render the Payload data?



    The CoverBlockComponent contains a cover image with rich text overlaying. Here is a reference:

    https://www.figma.com/file/4I9fVoyduxn0W1EMXVwAjO/2160---Hotel-Template-1---Bukela?node-id=0-1&t=S2Q6S7wHtYWz6TmD-0

    What I've done is to create a CoverBlockFields.ts file to define the fields of the block. The component logic happens in the CoverBlockComponent.ts file:



    import Image from "next/image";
    import { Block } from 'payload/types';
    import RichText from "../../components/RichText";
    import { CoverBlockType } from "./CoverBlockFields";
    import React, { ReactElement } from 'react';
    
    const CoverBlockComponent: React.FC<CoverBlockType> = (props) => {
      const { content, image } = props;
    
      return (
        <RichText
        className={classes.caption}
        content={caption}
      />
      <NextImage
              src={`${process.env.NEXT_PUBLIC_SERVER_URL}/media/${filenameToRender}`}
              alt={image.alt}
              sizes={sizesToUse}
              width={width}
              height={height}
            />
      );
    };`
    
    export default CoverBlockComponent;


    I assume this code is very wrong and missing logic as I don't yet understand how to render data from the server and to use Typescript.



    I've created a page called CoverPage.tsx to render the block:


    import React from 'react';
    import { CoverBlockComponent } from '../components/CoverBlockComponent';
    import { CoverBlockType } from '../blocks/CoverBlock/CoverBlockFields';
    
    export const getServerSideProps = async () => {
      const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/blocks`);
      const blocks = await res.json();
      return { props: { blocks } };
    };
    
    const CoverBlockComponent = (props) => {
      const { blocks } = props;
      return (
        <CoverBlockComponent />
      );
    };
    };
  • default discord avatar
    thisisnotchris
    2 months ago

    Looking good!



    Are there any issues?

  • default discord avatar
    Taun
    2 months ago

    Yea -

    "Server Error
    ReferenceError: BlocksContent is not defined
    
    This error happened while generating the page. Any console logs will be displayed in the terminal window.
    Source
    blocks\Content\BlocksContent.tsx (24:15) @ BlocksContent
    
      22 | };
      23 | 
    > 24 | export default BlocksContent; 


    // BlocksContent.tsx located in blocks/Content


     import React from 'react';
    import RichText from '../../components/RichText';
    import classes from './index.module.css';
    
    export type Type = {
      blockType: 'content'
      blockName?: string
      content: unknown
    }
    
    export const Component: React.FC<Type> = (props) => {
      const { content } = props;
    
      return (
        <div className={classes.wrap}>
          <RichText
            content={content}
            className={classes.content}
          />
        </div>
      );
    };
    
    export default BlocksContent;
  • default discord avatar
    thisisnotchris
    2 months ago

    Where are you using BlocksContent, that error seems like you're not importing it



    I can see it's being exported from the code above



    But where is it imported

  • default discord avatar
    Taun
    2 months ago

    Do I need BlocksContent to render the block? I can delete it right?



    Or is it required for Payload?

  • default discord avatar
    thisisnotchris
    2 months ago

    Hmmm



    So you're trying to create a custom block?



    I think you just want to export the Component



    because BlocksContent doesn't seem like something defined in your file

  • default discord avatar
    Taun
    2 months ago

    Yea, I don't know what BlocksContent is or if it's needed. I deleted it.



    I'm now not getting any errors in the console, though getting error

    coverpage:1          GET http://localhost:3000/coverpage 500 (Internal Server Error)

    in Chrome inspector for

    http://localhost:3000/coverpage

    Payload admin page works.



    I'll restart the server now and try again



    Yea still getting error:

     Failed to load resource: the server responded with a status of 500 (Internal Server Error) 


    I added the BlocksContent.tsx file back and it's working again, but now returning a different error:



    The VScode terminal isn't showing any errors - all good that side.



    Failed to load resource: the server responded with a status of 404 (Not Found)
    image.png
  • default discord avatar
    thisisnotchris
    2 months ago

    So that means your client request is invalid



    (the 500)

  • default discord avatar
    Taun
    2 months ago

    Now I'm just getting the 404 with that screenshot err of missing components



    I'm confused about rendering blocks. I've created the CoverBlock component block that contains a cover image with rich text over it. I assume I can add that block to a page and upload data using the Payload admin panel. How do I render that specific uploaded data? The CoverBlockCompent file handles that logic right?



    THere's a lot of squigglies happening here:



    I don't think it's exporting CoverBlockComponent... when I try to import it to render to the CoverBlock page it can't find it.



     const CoverBlockComponent: React.FC<CoverBlockType>
    Type '(props: PropsWithChildren<CoverBlockType>) => { classes: any; "": any; }' is not assignable to type 'FC<CoverBlockType>'.
      Type '{ classes: any; "": any; }' is missing the following properties from type 'ReactElement<any, any>': type, props, keyts(2322)


    CoverBlocksComponent.ts



     import Image from "next/image";
    import { Block } from 'payload/types';
    import RichText from "../../components/RichText";
    import { CoverBlockType } from "./CoverBlockFields";
    import React, { ReactElement } from 'react';
    
    const CoverBlockComponent: React.FC<CoverBlockType> = (props) => {
      const { content, image } = props;
    
      return (
        <RichText
        className={classes.caption}
        content={caption}
      />
      <NextImage
              src={`${process.env.NEXT_PUBLIC_SERVER_URL}/media/${filenameToRender}`}
              alt={image.alt}
              sizes={sizesToUse}
              width={width}
              height={height}
            />
      );
    };`
    
    export default CoverBlockComponent;


    Yea I don't know what I'm doing, definetly some issues with the components. I'll take a look tomorrow morning.

    image.png
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.