Search code examples
javascriptwordpressgraphqladvanced-custom-fieldsgatsby

Using ACF with GraphQL and Gatsby, flexible content is not returning the order of it's child blocks


I have a Gatsby site that is hooked up to use Wordpress as a headless CMS. I am using ACF to create dynamic layouts in Wordpress then rendering the modules I add to page to the frontend(Gatsby). I am using the flexible content feature in ACF to dynamically create layouts in the cms that can be easily rendered in React. Normally I do this with next.js and Wordpress's REST API which returns the "flexible content" data as an array of objects I can easily iterate over and render the appropriate content with.

My issue is that with using GraphQL and Gatsby, my "flexible content" data I get it back from the API is just a bunch of objects within the parent page's object body. This means there is no relationship to what order the modules/children were placed in the flexible content block since they aren't part of an array. My workaround, for the time being, is to add an extra field to the child modules that specify its' order on the page based on a number value.....but this is gross and would be a horrible experience for a client so I am not happy with that.

Is there a way to either return a value for each item in an AFC flexible content block that directly relates to its index/position. Or is there a way to return the children items in an array when using the Gatsby plugin for returning data.

Currently, my query looks a little like this:

allWordpressPage {
  edges {
    node {
      id
      slug
      status
      template
      title
      childWordPressAcfFeaturedShowcaseCarousel {
        id
        title
        other_stuff
      }
      childWordPressAcfIphonesAndContent {
        id
        title
        other_stuff
      }
      childWordPressAcfContentAndImageSlideShow {
        id
        title
        other_stuff
      }
    }
  }
}

That will return something like:

{
  id: 123,
  slug: 'hello',
  template: 'default',
  title: 'Help Me',
  childWordPressAcfFeaturedShowcaseCarousel: {
    id: 1232
    title: 'Bonjour'
    other_stuff: {....}
  },
  childWordPressAcfIphonesAndContent: {
    id: 1232
    title: 'Bonjour'
    other_stuff: {....}
  },
  childWordPressAcfContentAndImageSlideShow: {
    id: 1232
    title: 'Bonjour'
    other_stuff: {....}
  }
}

But instead, I would want something like:

{
  id: 123,
  slug: 'hello',
  template: 'default',
  title: 'Help Me',
  childWordPressAcfFeaturedShowcaseCarousel: {
    id: 1232,
    index: 1,
    title: 'Bonjour',
    other_stuff: {....}
  },
  childWordPressAcfIphonesAndContent: {
    id: 1232,
    index: 2,
    title: 'Bonjour',
    other_stuff: {....}
  },
  childWordPressAcfContentAndImageSlideShow: {
    id: 1232,
    index: 3,
    title: 'Bonjour'
    other_stuff: {....}
  }
}

Or even better:

{
  id: 123,
  slug: 'hello',
  template: 'default',
  title: 'Help Me',
  module: [
    childWordPressAcfFeaturedShowcaseCarousel: {
      id: 1232,
      title: 'Bonjour',
      other_stuff: {....}
    },
    childWordPressAcfIphonesAndContent: {
      id: 1232,
      title: 'Bonjour',
      other_stuff: {....}
    },
    childWordPressAcfContentAndImageSlideShow: {
      id: 1232,
      title: 'Bonjour'
      other_stuff: {....}
    }
  ]
}

Solution

  • So I just figured it out. Turns out when querying data for a flexible content block there are a few things to remember. To access flexible content fields, instead of using their field name, you need to use [field_name]_[post_type] (if you have field named page_builder in your WordPress pages you would need to use page_builder_page). Once you do that everything will return in an array in the exact order they are in the ACF block.

    So now my query looks like this:

    allWordpressPage {
      edges {
        node {
          id
          slug
          status
          template
          title
          acf {
            modules_page {
              ... on WordPressAcf_featured_showcase_carousel {
                __typename
                id
                title
                other_stuff
              }
              ... on WordPressAcf_iphones_and_content {
                __typename
                id
                title
                other_stuff
              }
              ... on WordPressAcf_content_and_image_slide_show {
                __typename
                id
                title
                other_stuff
              }
            }
          }
        }
      }
    }