Query linked content in nested page slice

I'm trying to retrieve a page using NextJS and prismic/client.

My page has multiple slices and one of those slices has a linked content relationship.

So my tree would look something like this:

- page
-- slices
--- faq_slice
---- title
---- faq_question (repeatable content relationship)
--- other_slice
---- title

page.json:

{
  "id": "page",
  "label": "page",
  "repeatable": true,
  "status": true,
  "json": {
    "Main": {
      "uid": {
        "type": "UID",
        "config": {
          "label": "uid",
          "placeholder": "Page Slug"
        }
      },
      "title": {
        "type": "Text",
        "config": {
          "label": "title",
          "placeholder": "Page browser title"
        }
      },
      "body": {
        "type": "Slices",
        "fieldset": "Slice Zone",
        "config": {
          "choices": {
            "body_content": {
              "type": "SharedSlice"
            },
            "points_of_service": {
              "type": "SharedSlice"
            },
            "content_and_image_header": {
              "type": "SharedSlice"
            },
            "credit_refund": {
              "type": "SharedSlice"
            },
            "card": {
              "type": "SharedSlice"
            },
            "cta_block": {
              "type": "SharedSlice"
            },
            "personal_card_flow": {
              "type": "SharedSlice"
            },
            "table": {
              "type": "SharedSlice"
            },
            "faq_block": {
              "type": "SharedSlice"
            },
            "anonymous_card_travel_history": {
              "type": "SharedSlice"
            },
            "cancel_credit_order": {
              "type": "SharedSlice"
            },
            "contact_form_iframe": {
              "type": "SharedSlice"
            },
            "credit_order_form": {
              "type": "SharedSlice"
            },
            "email_service": {
              "type": "SharedSlice"
            },
            "hero_banner": {
              "type": "SharedSlice"
            },
            "retrieve_usernames_form": {
              "type": "SharedSlice"
            }
          }
        }
      }
    },
    "Meta": {
      "metaTitle": {
        "type": "Text",
        "config": {
          "label": "Meta Title",
          "placeholder": ""
        }
      },
      "metaDescription": {
        "type": "Text",
        "config": {
          "label": "Meta Description",
          "placeholder": ""
        }
      }
    }
  }
}

faq_question is a custom type with a key text and a rich text field.

{
  "id": "faq_question",
  "label": "FAQ Question",
  "repeatable": true,
  "status": true,
  "json": {
    "Main": {
      "question": {
        "type": "Text",
        "config": {
          "label": "Question",
          "placeholder": ""
        }
      },
      "answer": {
        "type": "StructuredText",
        "config": {
          "label": "Answer",
          "placeholder": "",
          "allowTargetBlank": true,
          "multi": "paragraph,preformatted,heading1,heading2,heading3,heading4,heading5,heading6,strong,em,hyperlink,image,embed,list-item,o-list-item,rtl"
        }
      },
      "slices": {
        "type": "Slices",
        "fieldset": "Slice Zone",
        "config": {
          "choices": {}
        }
      }
    }
  }
}

Because everything is statically generated, I'm retrieving my page inside getStaticProps

// [uid].ts
export const getStaticProps: GetStaticProps = async ({
  params,
  locale,
  defaultLocale,
  previewData,
}) => {
  //...
  const page = await client.getByUID('page', `${params?.uid}`, { lang });
  //..
};

However, since faq_question is a content relationship it's content is not directly available inside my slice.

I've tried querying by using fetchLinks:

const page = await client.getByUID('page', `${params?.uid}`, 
  { lang, fetchLinks: ['faq_question.question', 'faq_question.answer'] });

But this only returns the first paragraph of rich text items.

I've also tried writing a graphquery for page:

export const pageGraphQuery = `{
  page {
    ...pageFields
    body {
      ...bodyFields
      ...on faq_block {
        variation {
          ...on default {
            primary {
              ...primaryFields
            }
            items {
              ...itemsFields
              faq_question {
                ... on faq_question {
                  ...faq_questionFields
                }
              }
            }
          }
        }
      }
    }
  }
}`;

I'd like to spread all other slice fields (hence the ...bodyFields), and only overwrite the faq_block but this is not a valid query.

Any pointers on how I can better query for content relationships like this would be greatly appreciated!

Hey @Zeebaarstiaan, thanks for reaching out.

I can't see the Content Relationship field that's named the same as the faq_question Type in the Page type, can you show us the entire JSON?

Sure!

I forgot to add the faq_block slice. This slice has the content relationship with faq_question:

{
  "id": "faq_block",
  "type": "SharedSlice",
  "name": "FaqBlock",
  "description": "FaqBlock",
  "variations": [
    {
      "id": "default",
      "name": "Default",
      "docURL": "...",
      "version": "sktwi1xtmkfgx8626",
      "description": "FaqBlock",
      "primary": {
        "title": {
          "type": "Text",
          "config": {
            "label": "Title",
            "placeholder": ""
          }
        }
      },
      "items": {
        "header": {
          "type": "Text",
          "config": {
            "label": "Header",
            "placeholder": ""
          }
        },
        "content": {
          "type": "StructuredText",
          "config": {
            "label": "Content",
            "placeholder": "",
            "allowTargetBlank": true,
            "multi": "paragraph,preformatted,heading1,heading2,heading3,heading4,heading5,heading6,strong,em,hyperlink,image,embed,list-item,o-list-item,rtl"
          }
        },
        "faq_question": {
          "type": "Link",
          "config": {
            "label": "FAQ Question",
            "select": "document",
            "customtypes": [
              "faq_question"
            ]
          }
        }
      },
      "imageUrl": "https://images.prismic.io/slice-machine/621a5ec4-0387-4bc5-9860-2dd46cbc07cd_default_ss.png?auto=compress,format"
    }
  ]
}

Here is an updated version of your query. In Slice Machine the Slices are inside slices, in the Legacy builder they are in body.

Following the line of Slice Machine this would be your query:

export const pageGraphQuery = `{
  page {
    ...pageFields
    slices {
      ...on faq_block {
        variation {
          ...on default {
            primary {
              ...primaryFields
            }
            items {
              ...itemsFields
              faq_question {
                ... on faq_question {
                  ...faq_questionFields
                }
              }
            }
          }
        }
      }
    }
  }
}`;

This should work to return the faq_question Custom Type fields.

I noticed that you tried to get all the fields inside the body with ...bodyFields. This isn't accurate. To return all the fields of each Slice created with the Slice Machine, it is necessary to make a union select for each "primary" and "items" section. Here's an example:

Thanks for the reply.

We're actually using the 'body' attribute instead of 'slices' since this json was created with an earlier version of slicemachine, so the query was already working.

My main point was that I was unable to query both bodyFields and a specific union type, but I'm guessing that is just not possible. Not without explicitly declaring each union type at least.

I see. Thanks for sharing that.
Yes, you need to specify each section.