How do I name page templates for nested dynamic routing in Next?

I'm trying to achieve a dynamic routing structure that allows for a bit more freedom in the routing. Essentially, I have a page type called landing, that I'm able to route to within my [uid] template, using { uid } = params in my getServerSideProps function. However, I want to allow users to visit that same page via a subdirectory, such as mysite.com/sacramento-ca/landing-page . The research that I've done seems to indicate that I can create a content relationship within my repository that references a document that can be the top level ( sacramento-ca being the example here), and then reference those in my query, and pass that to the page template. However, I can't figure out how to make that happen.

My pages directory is structured like this:

├── [uid]
│   └── index.tsx
├── index.tsx
├── products
│   └── [uid].tsx
├── projects
│   └── index.tsx
├── promos
│   ├── [id].tsx
│   └── index.tsx
└── sitemap
    └── index.tsx

..and overall this works just fine for top level pages. But 1. how can I query the category in getServerSideProps and how would I name and nest the page templates? I read this question/answer on Stack Overflow as well, and that seems like it's on the right track, but I'm not sure how to make it happen. Here is the code for my [uid] template as well, in case that's helpful.

import React from 'react';

import { SEO } from 'components/seo/SEO';
import { SliceZone } from 'components/slice-zone/SliceZone';

import { client, queryWithProducts } from '../../lib/prismic';

export const Page = ({ document }: any) => {
  const slices = document;
  if (!slices) return null;

  const { meta_title, meta_description, meta_keywords, social_image } = document;

  return (
    <>
      <SEO
        title={meta_title}
        description={meta_description}
        keywords={meta_keywords}
        banner={social_image.url}
      />
      <SliceZone slices={slices} />
    </>
  );
};

export default Page;

export const getServerSideProps = async ({ params, query }: any) => {
  console.log(query)
  const { uid } = params;
  const { data: document } = await client.getByUID('landing', uid, queryWithProducts);

  return {
    props: {
      document,
    },
  };
};

Hey @jesse,

This is a good question. I'll try to answer it as best I can, but please let me know if I've misunderstood your use case.

As I understand, you'd like to be able to render a page at:

mysite.com/<category>/<uid>

If that's the case, you'll want a folder structure like this:

.
└── pages
    └── [category]
        └── [uid].js

Then, you can destructure { category, uid } = params. With those two values, you can query your page by UID or by category — or both — as you like.

If you want to query your content by the category, you'll need to first query the category itself to retrieve the Document ID (not the UID) for the category, which is a short randomized string, which looks like WNje3SUAAEGBu8bc. With the category's Document ID, you can do a query by Content Relationship.

With that configured, you Next app should deliver the page at /sacramento-ca/landing-page.

The next step is to configure your internal links. With multi-part dynamic links like this, it's tricky to do with the Link Resolver. That's why we recently created a Route Resolver for Next.js. If you look at Example 3 on this page, it explains how to use the Route Resolver to generate a link for a page with a parent page.

I hope that's clear. Please take a look and let me know if you have any questions :slight_smile:

Best,
Sam

Thanks for this, very helpful! Is there a way to dynamically get the Document ID server side? Because, essentially, I need these pages to be reachable from any number of dynamic routes.

Secondly, I changed my client query to this:

const response = await client.query([
    Prismic.Predicates.at('document.type', 'landing'),
    Prismic.Predicates.at('my.landing.dealers.dealer', 'WNje3SUAAEGBu8bc'),
]);

and while it doesn't give me an error page anymore, it just gives me a 404. Assuming my content relationship is named dealers should my folder be structured like:

.
└── pages
    └── [dealer]
        └── [uid].js

This. with the folder named dealer? Thanks!

Hey @jesse,

I created a CodeSandbox to show you how I would do this. This is an example using my personal blog, so the route /sam/cool-shapes shows the blog post with the UID "cool-shapes" and the author with a UID of "sam." The same principle applies to a page with a parent page.

Within getServerSideProps, I do a getByUID query to get the ID of the category, and then I do a query to get a document by the category and UID.

You can name the folder however you like, as that is just the name of the parameter in Next.js.

Let me know if this helps. If it doesn't help, or you're still getting your 404, you could send me your project files in a ZIP file or GitHub repo, and I could take a closer look to see what could be causing the issue.

Best,
Sam

Hi again, Sam! Yeah, I'm still getting a 404 using this. I would certainly send a zip folder or my GitHub repo. Thanks!

Perhaps it could be due to the fact that I need to have multiple categories available? It's a group field.

Nevermind, I figured this out!

1 Like

@jesse Great! Let me know if you have any more questions.

This issue has been closed as it has been fixed, Flag if it is not the case for you to reopen.