# Dynamic pages and nested children

**URL:** <https://community.prismic.io/t/dynamic-pages-and-nested-children/6402>\
**Category:** Developing with Prismic\
**Tags:** nextjs\
**Created:** [July 26, 2021, 3:10pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402 "2021-07-26T15:10:24Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![amos](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@amos](https://community.prismic.io/u/amos)\
**Post date:** [July 26, 2021, 3:10pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/1 "2021-07-26T15:10:24Z")

</div>

I've been trying to follow [Define Paths with Next.js - Prismic](https://prismic.io/docs/technologies/the-route-resolver-nextjs) to implement something that should be very simple: namely dynamic routing.

In my case I have basic pages such as `/about`, `/faq` etc. and also pages related to cities `/copenhagen` and `/munich` for example. Now I want to add the possibility to create a city page, e.g. `/copenhagen/apartments` and for this I thought I could simply create a custom type called "city" and a custom type called a "city page" with a relationship to the city (imagine the "article" custom type from the article linked above, but instead of a category it's a city). Since I can't have both `[city]/[uid].tsx` and `[uid].tsx` with Next.js, I'm a bit lost on how to implement this.

Seems like [NextJS - dynamic page and dynamic folder at root level - possible?](https://community.prismic.io/t/nextjs-dynamic-page-and-dynamic-folder-at-root-level-possible/6309) is similar to my problem, but I am not satisfied with any of the answers given there. It seems the only way to do it is to namespace your folder routes (e.g. `/cities/[city]/[uid]`) but then I am not sure how to create a page such as `/cities/copenhagen` on the Prismic dashboard. Either way, the documentation is imo very lacking in this case (nothing mentioned about `useGetStaticProps`) and does not even work in some cases (`const [section, category, uid] = doc.url.split('/')` does not work since the url starts with a `/`, so it will not be split correctly).

Any suggestions are very much appreciated!

---

<div class="post-metadata">

**Author:** ![Priyanka](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/priyanka/32/3223_2.png) [@Priyanka](https://community.prismic.io/u/Priyanka)\
**Post date:** [July 28, 2021, 9:43am UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/3 "2021-07-28T09:43:29Z")

</div>

Hello @amos

Thanks for posting this question to us.

I remember I have discussed the same type of query before with one of my clients. This thread might be useful for you, it's in Nuxt.js [Nuxt with SM Routes - #31 by Priyanka](https://community.prismic.io/t/nuxt-with-sm-routes/2723/31)

Let me know if you have any doubts.

Thanks,  
Priyanka

---

<div class="post-metadata">

**Author:** ![amos](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@amos](https://community.prismic.io/u/amos)\
**Post date:** [July 28, 2021, 2:43pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/4 "2021-07-28T14:43:40Z")

</div>

I'm not using Nuxt, but Next, which has file-system based router and is the cause of my problem. I also don't know how Vue's router works (the part with `asyncData` and querying the right UID), so not sure if this is really that useful to me, but I will have a look. Would be great if you could show me something related to Next.js as well, though!

---

<div class="post-metadata">

**Author:** ![Priyanka](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/priyanka/32/3223_2.png) [@Priyanka](https://community.prismic.io/u/Priyanka)\
**Post date:** [July 29, 2021, 11:32am UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/5 "2021-07-29T11:32:08Z")

</div>

Hello @amos ,

Can you try with the following file structure in next.js:

```auto
/pages
	index.js —> url:/
	/cities
		index.js —> url:/cities
		/[id]
			index.js —>url:/cities/[city]
			/[id]
			index.js —> url:/cities/[city]/[uid]

```

Reference: [Routing: Dynamic Routes | Next.js](https://nextjs.org/docs/routing/dynamic-routes)

Hope it helps.

Thanks,  
Priyanka

---

<div class="post-metadata">

**Author:** ![amos](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@amos](https://community.prismic.io/u/amos)\
**Post date:** [July 29, 2021, 11:45am UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/6 "2021-07-29T11:45:07Z")

</div>

Hi @Priyanka,

It's not necessarily the file structure that is the problem for me. It's mainly how I should set up the "City Page" custom type, the router in my Prismic configuration and how I should then query this in the Next.js page. I already did the following and it's sort of working, but I don't think it's the correct way of doing things:

```auto
// City Page custom type
"city" : {
  "type" : "Link",
  "config" : {
    "select" : "document",
    "customtypes" : ["city"],
    "label" : "City",
    "placeholder" : "city"
  }
},
"uid" : {
  "type" : "UID",
  "config" : {
    "label" : "UID",
    "placeholder" : "unique-identifier-eg-apartments"
  }
},

```

and the following file structure

```auto
/cities
  /[city]
    index.tsx —>url:/cities/[city]
    /[uid]
      index.tsx —> url:/cities/[city]/[uid]

```

I then have this in my Prismic configuration:

```auto
export const linkResolver = (doc) => {
  if (doc.type === "page") {
    return `/${doc.uid}`;
  }
  return "/";
};

export const Router = {
  routes: [
    {
      type: "page",
      path: "/:uid",
    },
    {
      type: "home-page",
      path: "/",
    },
    {
      type: "city-page",
      path: "/cities/:city?/:uid",
      resolvers: {
        city: "city",
      },
    },
  ],
  href: (type) => {
    const route = Router.routes.find((r) => r.type === type);
    return route && route.href;
  },
};

```

which is probably wrong, as I have to do the following to make it work:

```auto
// /cities/[city]/index.tsx
export const getStaticProps = useGetStaticProps({
  client: Client(),
  type: "city-page",
  apiParams({ params }: any) {
    return {
      uid: params.city,
    };
  },
});

// eslint-disable-next-line react-hooks/rules-of-hooks
export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  type: "city-page",
  formatPath: (prismicDocument: any) => {
    return {
      params: {
        city: prismicDocument.uid,
      },
    };
  },
});

```

```auto
// /cities/[city]/[uid].tsx
export const getStaticProps = useGetStaticProps({
  client: Client(),
  type: "city-page",
  apiParams({ params }: any) {
    return {
      uid: params.uid,
    };
  },
});

// eslint-disable-next-line react-hooks/rules-of-hooks
export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  type: "city-page",
  formatPath: (prismicDocument: any) => {
    if (!prismicDocument.data.city.slug) {
      return {
        params: {
          uid: prismicDocument.uid,
          city: prismicDocument.uid,
        },
      };
    }

    return {
      params: {
        uid: prismicDocument.uid,
        city: prismicDocument.data.city.slug,
      },
    };
  },
});

```

So for e.g. `/cities/new-york` I will create a City Page with just the `uid` field set to `new-york`, and for e.g. `/cities/new-york/apartments` I would create another page with the `city` field set to the City custom type `New York` and the `uid` set to `apartments`.

I am obviously missing something or doing it wrong, as the double return above does not make sense and I am only doing it because I get the following error if I don't: `A required parameter (city) was not provided as a string in getStaticPaths for /cities/[city]/[uid]`. If you could help me out with this, it would be very much appreciated!

---

<div class="post-metadata">

**Author:** ![Priyanka](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/priyanka/32/3223_2.png) [@Priyanka](https://community.prismic.io/u/Priyanka)\
**Post date:** [July 30, 2021, 2:39pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/7 "2021-07-30T14:39:45Z")

</div>

Hello @amos

It will be better if you can share the Github project code and the URL of the Prismic repository?

Thanks,  
Priyanka

---

<div class="post-metadata">

**Author:** ![amos](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@amos](https://community.prismic.io/u/amos)\
**Post date:** [July 31, 2021, 9:10am UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/8 "2021-07-31T09:10:19Z")

</div>

Hi @Priyanka

The GitHub repository is private so I can't share that, but I think I have posted all the relevant code above already so that should be fine. The Prismic repositry is [https://joinlifex.prismic.io/](https://joinlifex.prismic.io/).

---

<div class="post-metadata">

**Author:** ![Priyanka](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/priyanka/32/3223_2.png) [@Priyanka](https://community.prismic.io/u/Priyanka)\
**Post date:** [August 4, 2021, 11:54am UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/9 "2021-08-04T11:54:14Z")

</div>

Hi @amos ,

First, I checked your repository and I couldn't find city-page documents.

If I understand your content structure correctly. You need to prepare 2 custom types:

1. `city`: for the pages like `NewYork`
2. `city-page` : For the pages like 'apartments'  
You create a content relationship in `city-page` with `city` for ex: for apartments, create a content-relationship here with city `NewYork`

Now on Front-end:  
When you use `/cities/:city?/:uid` : it means that `city` param is optional here, not required. for making it required, you need to remove the `?` after city.  
so when we say:

Now there are 2 cases:

1. When city is required- \>/cities/:city/:uid

```auto
/pages
	index.js —> url:/
	/cities
		/[:city]
			index.js —>url:/cities/[city] ----> for pages like Newyork
			/[:uid]
			index.js —> url:/cities/[city]/[uid] ----> for pages like Apartments

```

It means when we hit the URL with `/cities/new-york/apartments`, then under `/cities/:city/:uid`, you can get the city basic data using the content relationship fetch query.

1. When city is optional- \>/cities/:city?/:uid  
in this case, both URLs like /cities/apartments and /cities/newyork/apartments can behave the same way.

The best way is to have the content relationship between custom type city and city-page as mentioned above.

Let me know if you have any other doubts.

Thanks,  
Priyanka

---

<div class="post-metadata">

**Author:** ![amos](https://avatars.discourse-cdn.com/v4/letter/a/ebca7d/32.png) [@amos](https://community.prismic.io/u/amos)\
**Post date:** [August 9, 2021, 7:53am UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/10 "2021-08-09T07:53:47Z")

</div>

Hi,

As I mentioned before ([Dynamic pages and nested children - #6 by amos](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/6) ), I had done exactly what you suggest and it does not work properly when building pages, so I ended up changing it to have a "city home page" custom type (e.g. `/newyork`) and a "city page" custom type (e.g. `/newyork/apartments`). It is not an ideal solution, but it seems to work...

---

<div class="post-metadata">

**Author:** ![Priyanka](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/priyanka/32/3223_2.png) [@Priyanka](https://community.prismic.io/u/Priyanka)\
**Post date:** [August 11, 2021, 4:30pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/11 "2021-08-11T16:30:21Z")

</div>

Hello @amos

Can you explain a bit more, please? Why is this setup is not working? Did you get any errors with the suggested setup?

Thanks,  
Priyanka

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/system/32/1746_2.png) [@system](https://community.prismic.io/u/system)\
**Post date:** [August 18, 2021, 3:35pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/12 "2021-08-18T15:35:27Z")

</div>

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

---

<div class="post-metadata">

**Author:** ![system](https://dub1.discourse-cdn.com/flex013/user_avatar/community.prismic.io/system/32/1746_2.png) [@system](https://community.prismic.io/u/system)\
**Post date:** [December 9, 2021, 3:31pm UTC](https://community.prismic.io/t/dynamic-pages-and-nested-children/6402/13 "2021-12-09T15:31:50Z")

</div>


