NextJS - dynamic page and dynamic folder at root level - possible?

Hey all,

That's not an entirely Prismic question, but was hoping that someone on here will let me know if this is possible.

Can I create a folder such as /pages/[folder]/[uid].js as well as /pages/[uid].js. If I do that, then it says that it can't because there are conflicting IDs since [folder] and [uid] are not the same.

For context, I want to use /pages/[uid].js for the Page custom type - for pages such as /about and contact-us while I want to dynamically create folders for content, such as /news/new-website and /resources/start-here/ dynamically.

If it's not possible, I can simple create the folders hard coded (what I've been doing up to now), such as /news/[uid].js and /resources/[uid].js but then the marketing team will need a bit of development help every time they want to create a new folder.

An alternative which I have not tried is to create a massive file using the catch-all method pages/[...uid].js but then I see that this file will become a mess, so I want to avoid it.

I've run into a similar issue recently, it does not seem possible to do that.

You can only have one dynamic page per level. I ended up restructuring the project a little bit and added everything that is dynamic under different folders

  • /blog/[category]/[uid]
  • /pages/[category]/[uid]

etc

The only problem that it generates is that the slug can't be translated. But that's a minor detail.

1 Like

Hey Team,

You can do this surely with the following structure:

 /pages/[category]/[index].js
 /pages/[category]/[uid].js

[index].js acts as the dynamic page for your [category] folder with a query like so:

import { Client, Router } from "../../../prismic-configuration";
import SliceZone from "next-slicezone";
import { useGetStaticProps, useGetStaticPaths } from "next-slicezone/hooks";

import resolver from "../../../sm-resolver.js";
import Layout from "../../../components/Layout";

const Page = (props) => {
  return (
    <Layout menu={props.menu}>
      <p>Category</p>
      <SliceZone {...props} resolver={resolver} />
    </Layout>
  );
};

export const getStaticProps = useGetStaticProps({
  client: Client(),
  type: 'category', // query document of type "page"
  queryType: 'repeat',
  apiParams({ params }) {
    return {
      uid: params.category,
      lang: 'en-gb'
    }
  },
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  formatPath: (prismicDocument) => {
    console.log(prismicDocument)
    return {
      params: {
        category: 'category-content-relationship'
      },
    }
  },
})

export default Page;

and the [uid].js page would look something like:

import { Client, Router } from "../../../prismic-configuration";
import SliceZone from "next-slicezone";
import { useGetStaticProps, useGetStaticPaths } from "next-slicezone/hooks";

import resolver from "../../../sm-resolver.js";
import Layout from "../../../components/Layout";

const Page = (props) => {
  return (
    <Layout menu={props.menu}>
      <SliceZone {...props} resolver={resolver} />
    </Layout>
  );
};

// Fetch content from prismic
export const getStaticProps = useGetStaticProps({
  client: Client(),
  apiParams({ params }) {
    return {
      uid: params.uid,
    }
  },
})

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  router: Router,
  formatPath: (prismicDocument, client) => {
    console.log(client)
    // const [category, uid] = prismicDocument.url.split('/')
    return {
      params: {
        category: 'category-content-relationship'
        uid: prismicDocument.uid
      },
    }
  },
})


export default Page;

Hey Phil,

Thanks for the quick answer! However, I'm not sure you understood my problem. I would like to have a folder /pages/[category]/ as well as /pages/[uid].js which is on the same level

I think I agree with David that at the moment, it is not possible in Nextjs

Yeah, I think I'm confused is this because /pages/[category]/ is querying the same custom type as /pages/[uid].js?

Yes exactly, so NextJS is throwing an error. It seems to be a limitation by NextJS and probably only fixable through a custom server

@kris What you're trying to do might actually be possible using a catch-all along with a normal dynamic route. According to the Next.js docs, a normal dynamic route will take precedence over a catch-all route.

That means that you should be able to have your /pages/[uid].js route for your /about and /contact-us pages.

Then you could also use a catch-all route such as /pages/[...uid].js for anything with a folder such as /news/new-website.

Give that a try and let us know if it works :slight_smile:

1 Like

Hi @levi , thanks a lot! That might just work - I just gave it a quick spin, but I also need to handle folder index pages (eg /news/) which are a different custom type so it will get a bit messy if I handle all of those in the same route.

You're very welcome :slight_smile:

Yeah handling the folder index pages makes this much more complicated. You will probably need to either hard code the folder categories as you mentioned or namespace your folder routes. Something like /pages/articles/[folder]/[uid].js.

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