Querying nested pages?

Hi,

For nested models how would you query for a specific page based on the slug (pathname) alone?

There are certain issues with querying a nested model with the same slug. i.e

/foo/bar and /bar/foo are different pages but querying this is very complex

Hello @david.hewitt

By nested models do you mean models linked by others, models in a tree-like structure, or models with modular content inside them?

Hey,

I am referring to tree-like structure models specificly.

The way I have it setup at the moment is to loop through all of the records in getStaticPaths and build up the paths array and create a mapping for the full slug and the id:

{
    'foo/bar': '32233-id',
    'bar/foo': '23434-id',
   'bar': '23443-id'
}

This gets stored in a file which I refer to later in the getStaticProps function.

So I can use the full slug from getStaticProps’s context to get the id and then query for the data.

I am not particularly happy with saving the slug and id’s to a file as it’s not particularly scalable.

I was wondering if you have a better solution or perhaps a way I can generate a dynamic tree structure in nextjs?

have you seen this page already: https://www.datocms.com/docs/content-delivery-api/tree-like-collections

can this help?

@david.hewitt

I think i have the exact solution for what you need, first here is one for fixed tree-depths, and a possible work around for dynamic tree-depths in the bottom of the post as well.

First, lets start with a structure of a tree with a fixed depth of one:

image

Now, if i want to generate the slugs for each child in the format “parentSlug/childSlug

I can simply do the following query:

query MyQuery {
  allTreeLikes(filter: {parent: {exists: "true"}}) {
    slug
    parent {
      slug
    }
  }
}

That will give us the following result:

Now, on the getStaticPropsFunction i can just build the slug by accessing this response and parsing it with a similar code:

for(const slugObject of response.data.allTreeLikes){
  return `${slugObject.parent.slug}/${slugObject.slug}`
}

Now, for dynamic tree depths, lets use this example, with a three of depth 2 now added to the previous example, making 2 trees of depth 1 and one tree of depth 2:

We now will use a modified version of the query, that asks for the parent slug as many times as the max depth of all trees (in this case, 2 times, as the max depth is 2)

query MyQuery {
  allTreeLikes(filter: {parent: {exists: "true"}}) {
    slug
    parent { //parent depth-1
      slug
      parent { //grandparent depth-2
        slug
      }
    }
  }
}

This will cause the trees that don’t have a grandchild to return a null in the last “parent slug” response:

You can still use the above “for loop” to iterate through this response and generate the slugs, however, now you would have to add some NULL checking to avoid the generation of invalid slugs for trees with depth < 2