Fetching nested content relationship fields

I have a mainMenu customtype which hold a Group of mainMenuItems with label and page_or_submenu fileds. page_or_submenu is a content relationship field which can hold either a page type or a submenu type. The submenu type also consists of a label and a page_or_submenu field.

So in Prismic i can create nested submenus in submenus with also can hold submenus and so on.

How would i fetch this? Because it seems that fetchLinks only fetches one level of submenus (no nested submenus) and with the graphQuery i tryed this:

    {
      main_menu {
        items {
            label
            page_or_submenu {
                ...on submenu {
                    items {
                        label
                        page_or_submenu {
                            ...on submenu {
                                items {
                                    label
                                    page_or_submenu {
                                        ...
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
      }
    }

Hello @davidmarkl,

You're correct that fetchLinks only fetches one level, so you'll need to use graphQuery. To help you build this query I'll need to see your content model in more details. Can you either share the JSON structure of your custom types? Or you can provide me the URL for your Prismic repository. If you don't want to share that publicly, you can send me a direct message.

Thanks,
Levi

Thanks for your answer!
So i have three custom types: the main menu which has an items group field for menu items, which can be either link to a page or to a submenu custom type (and some icons which we can ignore)

{
  "id": "main_menu",
  "label": "Main menu",
  "format": "custom",
  "repeatable": false,
  "status": true,
  "json": {
    "Main": {
      "items": {
        "type": "Group",
        "config": {
          "label": "Items",
          "fields": {
            "label": {
              "type": "Text",
              "config": {
                "label": "Label",
                "placeholder": ""
              }
            },
            "page_or_submenu": {
              "type": "Link",
              "config": {
                "label": "Page or Submenu",
                "select": "document",
                "customtypes": ["page", "submenu"]
              }
            },
            "icon_outlined": {
              "type": "Text",
              "config": {
                "label": "Icon outlined",
                "placeholder": ""
              }
            },
            "icon_filled": {
              "type": "Text",
              "config": {
                "label": "Icon filled",
                "placeholder": ""
              }
            }
          }
        }
      }
    }
  }
}

Then there is the submenu custom type which also has a items field with a link to either a page or a dropdown menu

{
  "id": "submenu",
  "label": "Submenu",
  "format": "custom",
  "repeatable": true,
  "status": true,
  "json": {
    "Main": {
      "uid": {
        "config": {
          "label": "UID"
        },
        "type": "UID"
      },
      "items": {
        "type": "Group",
        "config": {
          "label": "Items",
          "fields": {
            "label": {
              "type": "Text",
              "config": {
                "label": "Label",
                "placeholder": ""
              }
            },
            "page_or_dropdown": {
              "type": "Link",
              "config": {
                "label": "Page or Dropdown menu",
                "select": "document",
                "customtypes": ["page", "dropdown_menu"]
              }
            }
          }
        }
      }
    }
  }
}

and there is the dropdown custom type, which is the exact same as the submenu but i created it to add more clearness to the content editors

{
  "id": "dropdown_menu",
  "label": "Dropdown menu",
  "format": "custom",
  "repeatable": true,
  "status": true,
  "json": {
    "Main": {
      "uid": {
        "config": {
          "label": "UID"
        },
        "type": "UID"
      },
      "items": {
        "type": "Group",
        "config": {
          "label": "Items",
          "fields": {
            "label": {
              "type": "Text",
              "config": {
                "label": "Label",
                "placeholder": ""
              }
            },
            "page_or_dropdown": {
              "type": "Link",
              "config": {
                "label": "Page or Dropdown menu",
                "select": "document",
                "customtypes": ["page", "dropdown_menu"]
              }
            }
          }
        }
      }
    }
  }
}

So with these custom types you can nest them like this: First you have the main menu. The main menu can hold some submenus. The submenus then can hold some dropdown menus. And the dropdown menus can again hold some dropdown menus that also can hold dropdown menus and so on...
And i would like to be able to fetch this tree with a single fetch to the main menu.

If thats not possible i can also consider limiting myself to "just" two levels of dropdown menus as nobody will really ever use more or want more regarding UX.

Thanks in advance :D

@davidmarkl I can see the issue with your graphQuery. After the main_menu, you need to use the field page_or_dropdown instead of page_or_submenu. And the final ...on submenu should be ...on dropdown_menu. Here's what it should look like:

{
      main_menu {
        items {
            label
            page_or_submenu {
                ...on submenu {
                    items {
                        label
                        page_or_dropdown {
                            ...on dropdown_menu {
                                items {
                                    label
                                    page_or_dropdown {
                                        ...
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
      }
    }

Give that a try.