0

I'm was trying to look for ways to make my website load faster and after running speed tests I understood that I was making a mistake in the way I'm loading data from contentful. I have a page with all the blogs listed in it (with just their title and image and a handful other details visible in the list of blogs) and instead of loading only the necessary fields from contentful I'm loading all the fields for each array item(post) of the array posts which naturally takes up a lot of time and makes my page slow. How can I load only specific fields from contentful for the blog list page but load all the fields when we click on an individual blog from the list. I'm using react static and this is how my config file looks for the posts section where the path /blog is the main blog list page and /container/Post is the individual blog page.

let posts = await client
      .getEntries({
        content_type: "blogPost",
        order: "-sys.createdAt",
        include: 1,
      })
      .then((response) => response.items)
      .catch(console.error);
    console.log("Post -> ", posts.length);

    posts = posts.sort((a, b) => {
      let keyA = new Date(a.fields.date);
      let keyB = new Date(b.fields.date);
      // Compare the 2 dates
      if (keyA < keyB) return 1;
      if (keyA > keyB) return -1;
      return 0;
    });

And in my return statement

{
        path: "/blog",
        getData: () => ({
          posts,
        }),
        children: posts.map((post) => ({
          path: `/${urlBuilder(
            post.fields.url ? post.fields.url : post.fields.title
          )}`,
          template: "src/containers/Post",
          getData: () => ({
            post,
          }),
        })),
      },

This is how my posts returned from contentful looks like

enter image description here

Cassandra
  • 147
  • 1
  • 2
  • 15
  • Have you considered using GraphQL? You could easily grab only the data your interested this way. https://www.contentful.com/developers/docs/references/graphql/#/reference/schema-generation/entries – jrnxf Jul 02 '21 at 02:09
  • I'm a beginner in React and I've never used GraphQL, I've been using content delivery API from the contentful sdk – Cassandra Jul 02 '21 at 02:15

1 Answers1

2

You can achieve this using the select operator. What this translates into when using the contentful sdk is something like this:

const contentful = require('contentful')

const client = contentful.createClient({
  space: '<space_id>',
  environment: '<environment_id>',
  accessToken: '<content_delivery_api_key>'
})

client.getEntries({
  content_type: '<content_type_id>',
  select: 'sys.id,fields.<field_name>'
})
.then((response) => console.log(response.items))
.catch(console.error)

Pay special attention to the select: 'sys.id,fields.<field_name>' section. This is where you can specify only what fields you want returned.

Dharman
  • 30,962
  • 25
  • 85
  • 135
jrnxf
  • 744
  • 8
  • 22
  • Thank you for the answer but will doing this prevent me from getting all the remaining fields necessary for the individual blog pages? I still need all the fields for every item in the `posts` array for those individual blog pages – Cassandra Jul 02 '21 at 02:55
  • The request above should not be used/confused for a request to get all information you could ever need for a given blog page. When you route a user to a blog page you'll make another request for all of the data you need for that page. – jrnxf Jul 02 '21 at 03:00
  • Oh but wouldn't that make no difference in terms of increasing speed if we're still getting all the information in a different request – Cassandra Jul 02 '21 at 03:02
  • 1
    The difference is you're only getting "all the information" for ONE blog post, not every blog post. In other words the first request is for only the title, description, url, etc of every post (all you need to display the available posts). You then click on a post and are routed to that specific post. Obviously you need more information than just the title, description, and url once you get there, so you make a secondary request just for that posts information. – jrnxf Jul 02 '21 at 03:06
  • @dharman `select: 'sys.id,fields.'` doesn't seem like the right syntax – Cassandra Jul 02 '21 at 03:32
  • `fields.` is just a generic example they provide. Their documentation may be helpful to provide more clarity: https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/select-operator – jrnxf Jul 02 '21 at 03:39
  • yeah I checked out their documentation and couldn't find an efficient way to add more than 1 field as `fields.` works only for a single field – Cassandra Jul 02 '21 at 03:43
  • You'll need to separate with commas. e.g. `sys.id,fields.productName,fields.description,fields.updatedAt,fields.tags` – jrnxf Jul 02 '21 at 03:58
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/234430/discussion-between-cassandra-and-coloradocolby). – Cassandra Jul 02 '21 at 04:03