Sign in
Log inSign up
Component-based Website Development with React and the Cosmic JS CMS

Component-based Website Development with React and the Cosmic JS CMS

Tony Spiro's photo
Tony Spiro
·Jul 18, 2018

A common approach to website development is to build components that can be reused across different web pages. The benefit to this approach is that you end up doing less duplicate work by managing the components rather than managing duplicate content across different pages. Popular JavaScript frameworks like React, Vue and Angular utilize this concept on the application code level to much success. How can we benefit from this approach on the content management level?

In this tutorial I'm going to show you how to build a component-based website using React and the Cosmic JS CMS. The goal is to save developers and content managers time and provide a scalable content model.

Build the Content Model

  • Prereqs: This article assumes you have an understanding of Cosmic JS concepts: Object Types, Objects and Metafields. If you need to brush up on these concepts, go to the Getting Started guide.

Using Cosmic JS Object Types and Metafields, we can create composable components that can be used across website pages. For our example we will create three Object Types:

  1. Pages
  2. Sections (components used in Pages)
  3. Team Members (used in the Team Section)

Let's look at each Object Type:

Pages

All Pages will include the following:

  1. Title (Text)
  2. Content (HTML Textarea)
  3. Sections (Multiple Objects Relationship Metafield)

The Multiple Objects Relationship Metafield will be used to manage the Page Sections.

Metafields

Team Members

Metafields:

  1. Name (Text Metafield)
  2. Image (File Metafield)
  3. Quote (Plain Textarea Metafield)

Sections

The Sections Object Type will be more dynamic and allow for different Metafields.

Team Section

Metafields:

  1. Headline
  2. Multiple Object Relationship Metafield (Team)
  3. Name
  4. Image
  5. Quote

Add your team members:

Team Members

Signup Section

Metafields:

  1. Headline (Text Metafield)
  2. Image (File Metafield)
  3. Content (HTML Metafield)
  4. CTA (Text Metafield)

Add Sections to Pages Now that we have our Sections set up, we can add them to our Pages:

Sections

Code it up

Now that we have our content saved, let's do some coding. Download the React starter:

git clone https:github.com/cosmicjs/react-starter

Now go into the Page component and edit it to look like this:

// page.js
import SectionList from './section-list'
export default ({ page }) => (
  <div>
    <h1>{page.title}</h1>
    <div dangerouslySetInnerHTML={{__html: page.content}}></div>
    <SectionList sections={page.metadata.sections}/>
  </div>
)

As you can see, we've added Section List on our Page Object. Our Section List and Section components looks like this:

// section-list.js
import TeamSection from './sections/team'
import SignupSection from './sections/signup'
export default ({ sections }) => (
  <div>
    {
      sections.map(section => {
        if (section.metadata.team)
          return <TeamSection section={section} />
        if (section.metadata.cta)
          return <SignupSection section={section} />
      })
    }
  </div>
)
// signup.js
export default ({ section }) => (
  <div>
    <h3>{section.metadata.headline}</h3>
    <div dangerouslySetInnerHTML={{ __html: section.metadata.content }}></div>
    <div><img src={section.metadata.image.imgix_url} /></div>
    <div><button>{section.metadata.cta}</button></div>
  </div>
)
// team.js
export default ({ section }) => (
  <div>
    <h3>{section.metadata.headline}</h3>
    {
      section.metadata.team.map(person => {
        return (
          <div key={person._id}>
            <div>{person.metadata.name}</div>
            <div>{person.metadata.quote}</div>
            <div><img src={person.metadata.image.imgix_url} /></div>
          </div>
        )
      })
    }
  </div>
)

Output of the Section component is determined by the data passed via the section prop.

In Conclusion

The Cosmic JS CMS is a great solution for building component-based websites. In our example, we created a Page Object with a Multiple Object Metafield connected to a Sections Object Type to add our Section components. The benefit to this approach is that we can now manage the section content in one place and reuse it across pages without having to go into each page to edit duplicate data.

I hope you found this useful. If you have any further questions, join our community on Slack and reach out to us on Twitter.

Photo by Lance Anderson on Unsplash