How can I fetch content from a single page throught Contentful API in a NextJS website?

1.5k views Asked by At

I've found some guides here and there about sourcing from Contentful into NextJS, where you can feed a static blog with content. That's a starting point.

But as for single pages contents, I cannot reach any results using the API. Not sure why.

Here's some excerpt of the code I'm working on with comments to explain the structure.

// components/layout.js
(...)

import client from '../utils/contentful/client' // <-- This imports the call for contentful [const contentful = require('contentful')]

// The function bellow is supposed to reach the content and export it as a props, right?
export async function getStaticProps({entryId}) {
  const paginas = await client
  .getEntries({ content_type: "paginas" })
  .getEntry({ entry_id: entryId })
  .then((response) => response.items)
  return {
    props: {
      paginas
    },
  }
}

// This function bellow is called within the <Footer /> where I pass the entry_id as a props
export function ContatoPage({ pagina }) {
  getStaticProps(pagina) 
    // Is this how it works? Can I call this function getStaticProps() here so the 
    //props will be reached in the constant bellow?
  
const { titulo, content } = paginas.fields
  return (
    <Box>
      <Heading>{titulo}</Heading>
      <p>{content}</p>
    </Box>
  )
}


// There's a static contact info page hanging on every footer and I'm trying to fetch it's values from Contentful.

function Layout( ... ) {
return (
(...)
<Footer>
  <ContatoPage pagina="<entry_id>" /> // this is where I pass the string value for the page I'm trying to reach.
</Footer>
} 

export default Layout

Any thoughts or comments will be immensely appreciated.

1

There are 1 answers

0
Eduardo Oliveira On

I had a lot of trouble figuring this out and thanks to @stefan-judis, who pointed out the misuse of getEntries and getEntry together, I had a lead on the approach that would work better for this.

It is, in fact, documented, but for beginner users like me, sometimes documentation on contentful can be a little weird to get, due to the wide number of APIs and methods on fetching content.

What I did that worked for me was to set an async function where I called the entries using queries. I'm used to query content with Gatsby using graphQL so I misunderstood the logic - like I said, no experience enough.

// client-contentful.js <-- This is a simple caller for the client
const { createClient } = require('contentful')

const client = createClient({
  space: process.env.NEXT_PUBLIC_CONTENTFUL_SPACE,
  accessToken: process.env.NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN
})

module.exports = client

// ***.js
import client from 'client-contentful.js'

// Set content for the page 
export async function getStaticProps() {
  let data = await client.getEntries({
    content_type: 'paginas', // <-- set content_type
    'fields.slug': 'inicio'  // <-- filter the page with the slug (you can pass it as a props too)
  })
  return {
    props: {
      pagina: data.items[0] // <-- this will set the query as a prop
    }
  }
}

export function Page({ pagina }) {
  const { titulo, slug, section } = pagina.fields

      return (
        <main id={slug}>
            <h1>{titulo}</h1>
            <RenderSection section={section} />

        </main>
    )
}

You can use this in many ways, as it is documented in other places. This is a solution I found out after some struggle.

Now, I still have a problem with the section part, where I have entries in my pages that I'd like to render in a mapping. Working on it right now.