How to get a reusable custom types UID with Prismic Link?

I have a single custom type with a content relationship that links to repeat reusable custom types.

The navigation looks correct in the UI, and I don't need parent navigations to be links (some parent navigations have and don't have submenu), so they are just text.

Submenu

<PrismicNextLink key={index} field={item.label_link}>
      {item.label_text}
</PrismicNextLink>

Here are some issues:

  1. I created a page where this should be a submenu/subpage. The URL didn't ``look like this
    for-venues/first-submenu

or

for-venues/another-submenu

Instead, it looks like this.

/first-submenu

  1. I understand why it didn't have a parent path, but I have a UID, which it could use for it. How/can I use a UID with Prismic Link?

Hey @solution.stack99 ,

Here's my "off-the-cuff" answer...

If you're linking to something, shouldn't these be Page Types rather than custom types? If they are indeed page types, I think the URL property would include the path based on your routeResolver entries. If I am then making links to pages using the URL prop, I'm no longer reaching for PrismicNextLink, I'm reaching for next/link (Link) instead.

I hope that helps.

Thank you for helping!

I made it work as follows:

  1. Creating the Page Type for the subpage.

  2. In Route Resolvers includes a subpage and hard code /for-venues

{
    type: "subpage",
    path: "/for-venues/:uid",
  },

In app folder, create a for-venues folder, [uid] folder and page.tsx file.
app/for-venues/[uid]/page.tsx file

However, I wasn't sure if this was a good practice.

Will it always be "for-venues?" If it could be something else, you could create a keytext field or a content relationship field (that's how I did it, see below) called "subdirectory" and enter values like for-venues, for-vendors, etc...

I have done this on a project but on the page page type itself. Subdirectory in this case is a custom type. Here's my routeResolver for that:

{
    type: 'page',
    path: '/:subdirectory?/:uid',
    resolvers: {
      subdirectory: 'subdirectory',
    },
  },

In my src/app/[...uid]/page.tsx you'll see:

type Params = { uid: string[] }
export default async function Page({ params }: { params: Params }) {
  const client = createClient()
  const sitemetadata = await client.getSingle('sitemetadata')
  const uid = params.uid[params.uid.length - 1]
  const page = await client
    .getByUID('page', uid, {
      fetchLinks: [
        'subdirectory',
        'boardmember.uid',
        'boardmember.name',
        'boardmember.role',
        'boardmember.image',
        'news.title',
        'news.date_published',
        'news.featured_image',
        'news.excerpt',
        'news.news_url',
      ],
    })
    .catch(() => notFound())
    // blah blah blah
    // my generateStaticParams shows how I take 
    // the subdirectory and make it part of the UID

export async function generateMetadata({
  params,
}: {
  params: Params
}): Promise<Metadata> {
  const client = createClient()
  const uid = params.uid[params.uid.length - 1]
  const page = await client.getByUID('page', uid).catch(() => notFound())

  return {
    title: asText(page.data.title),
    description: page.data.metadescription,
  }
}

export async function generateStaticParams() {
  const client = createClient()
  const pages = await client.getAllByType('page', {
    fetchLinks: ['subdirectory'],
  })

  return pages.map(page => {
    if (page.url) {
      return { uid: page.url.split('/').filter(Boolean) }
    }
  })
}

Do you have only src/app/[...uid]/page in your project that fetches all the main pages and subpages?
Also, should I create each reusable custom type for each subpage?

For example,

  1. Create a reusable custom type.
  2. Create a keytext field (for-venues, about, etc)

I apologize if I don't understand it correctly.

Good morning (at least for me, it's morning) @solution.stack99 ,

The setup I'm explaining is not a rabbit hole I've enjoyed. Of all my projects, it's the only one using this catch-all page. It was necessary because this client was migrated from WordPress, and I didn't want to do many redirects. So, whenever possible, I try to avoid this setup.

If you're looking to recreate it because you "have to" as well, then allow me to suggest this:

Custom Type: Subdirectory

  "id": "subdirectory",
  "label": "Sub-Directory",
  "repeatable": true,
  "status": true,
  "json": {
    "Main": {
      "title": {
        "type": "Text",
        "config": {
          "label": "Title",
          "placeholder": ""
        }
      },
      "uid": {
        "type": "UID",
        "config": {
          "label": "UID",
          "placeholder": ""
        }
      }
    }
  }
}

Page Type: Page
just note the subdirectory relationship

{
  "id": "page",
  "label": "Page",
  "repeatable": true,
  "status": true,
  "format": "page",
  "json": {
    "Main": {
      "title": {
        "type": "StructuredText",
        "config": {
          "label": "Title",
          "placeholder": "Enter the page title",
          "allowTargetBlank": true,
          "single": "heading2"
        }
      },
      "hidepagetitle": {
        "type": "Boolean",
        "config": {
          "label": "Hide Page Title",
          "placeholder_false": "false",
          "placeholder_true": "true",
          "default_value": false
        }
      },
      "uid": {
        "type": "UID",
        "config": {
          "label": "UID",
          "placeholder": "This will be in the address bar"
        }
      },
      "metadescription": {
        "type": "Text",
        "config": {
          "label": "MetaDescription",
          "placeholder": "Describe the page's purpose for SEO"
        }
      },
      "metaimage": {
        "type": "Image",
        "config": {
          "label": "MetaImage",
          "constraint": {},
          "thumbnails": []
        }
      },
      "twitterimage": {
        "type": "Image",
        "config": {
          "label": "TwitterImage",
          "constraint": {},
          "thumbnails": []
        }
      },
      "canonicalurl": {
        "type": "Text",
        "config": {
          "label": "CanonicalUrl",
          "placeholder": "Leave empty unless needed"
        }
      },
      "subdirectory": {
        "type": "Link",
        "config": {
          "label": "Subdirectory",
          "select": "document",
          "customtypes": ["subdirectory"]
        }
      },
      "datepublished": {
        "type": "Date",
        "config": {
          "label": "DatePublished",
          "placeholder": "Optionally set published date"
        }
      },
      "slices": {
        "type": "Slices",
        "fieldset": "Slice Zone",
        "config": {
          "choices": {
            "content": {
              "type": "SharedSlice"
            },
            "features": {
              "type": "SharedSlice"
            },
            "hero": {
              "type": "SharedSlice"
            },
            "list": {
              "type": "SharedSlice"
            },
            "recipe_card": {
              "type": "SharedSlice"
            },
            "board_members": {
              "type": "SharedSlice"
            },
            "form": {
              "type": "SharedSlice"
            },
            "two_grid": {
              "type": "SharedSlice"
            },
            "image_container": {
              "type": "SharedSlice"
            },
            "disclosure": {
              "type": "SharedSlice"
            },
            "policy_and_advocacy": {
              "type": "SharedSlice"
            },
            "courses_stuff": {
              "type": "SharedSlice"
            },
            "timeline": {
              "type": "SharedSlice"
            },
            "featured_news": {
              "type": "SharedSlice"
            }
          }
        }
      }
    }
  }
}

Route Resolver
as shown in previous reply

const routes: prismic.ClientConfig['routes'] = [
  {
    type: 'homepage',
    path: '/',
  },
  {
    type: 'page',
    path: '/:subdirectory?/:uid',
    resolvers: {
      subdirectory: 'subdirectory',
    },
  },
]

I hope this helps some.

Sorry for the delay.

This is very helpful and thank you so much for showing this. I will try if I can replicate it.

1 Like