Get all old UIDs associated with a given document

I saw this other post asking if it's possible to get a list of all old UIDs for a given document. The response said no. It's not clear to me whether that post was to do with the old API or the GraphQL API.

Ideally I'd want to do this with the GraphQL API. Is there any way to do it? I want to have the full list of redirections available at static build time. I could query Prismic for the document associated with the UID given by the user at request time but I'd rather not take this route.

Use case: I want to redirect old UIDs to the new one.

Hey Bart, thanks for reaching out!

What did you meant with the old API?
You'll get the same response in both the REST API and GraphQL.

And to be able to redirect old UIDs to the new one you'll need to do a check. Please take a look at the response in this similar thread:

Unfortunately for statically generated websites, checking if the requested uid matches the current uid is not a valid solution. In this case we would need to be able to have the old uids in the API response as well and manually create redirects.

What we did for now is setting up a custom old uid field that we need to manually update if we eventually change an uid. It is not ideal but it works.

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

That's not really a suitable solution, I think. A UID can change more than once, and requiring the content editor to remember to enter those old UIDs into a custom field will not be at all reliable.

The one you call the REST API.

As Romain said, it's not a good solution for statically generated websites.

So then this is now a feature request:

Please expose the list of old UIDs as part of the document metadata available for querying via the GraphQL API. You already provide an array of the document's tags; it shouldn't be tricky to also provide an array of the document's UIDs.

This would enable a full list of redirections to be put together at site build time, which is a speed boost for the visitor. It also means that 404s don't need to hit your API with requests, which ought to be a win for you too.

1 Like

Thank you for the feedback. I added this conversation as an open feature request since, for the moment, there's still no option no perform a similar query.

1 Like

This is being tracked as an open feature request.

If you have another use-case for this feature, you can 'Flag' this topic to reopen. Please use the :heart: button to show your support for the feature and check out our Feature Request Guidelines.

where are we on this? we still need to create redirects at build time for static sites. without the uid history we can't do it and we are underperforming
worst, we can't easily maintain our website; we need to be able to change urls and generate redirects automatically, we can't maintain something ultra custom

If you need to do this right now, your best bet is probably to do a call via the old API. I think you can get the list of UIDs from that.

@bart Can you tell me what is the old API? what's the endpoint and is there still some doc?

https://prismic.io/docs/technologies/rest-api-technical-reference

unfortunately old uids are not sent via the rest api v2 (nor the v1)

Hi @sebastien.vassaux & @bart,

It's funny we were discussing this exact use case here in the office for our documentation website just yesterday.

In the past, when not as many websites were statically deployed, this wasn't as much of an issue as the old UID's would still be able to query new content and not cause broken links as it does now with statically deployed sites since the queries aren't being run client-side. This means you need to maintain large redirect files for each time a UID is updated, as we do for our website.

The solution isn't currently being worked on but the team is now aware of this issue and we will start exploring options for some sort of UID management or a returned list of old UID's in the API which would help build redirects. If/when the team has any questions or updates about any of this they'll update you. here.

We haven't found a workaround for the moment, but if we find one for our own use case we will also add it here.

Thanks.

Hi @Phil ! Thanks, I'll be waiting for this :slight_smile: !

1 Like

I could have sworn they were available somewhere. Maybe my mind playing tricks with me. Sorry.

Hi @sebastien.vassaux & @bart ,

I talked with Levi here in the team and he created a workaround for this when building our documentation website that re-directs to the correct page when you use the old UID. It basically involves running the query live if the UID is not in the static list, it searches the API and returns the document with the old UID. If the UID doesn't exist anywhere the standard 404 is returned.

Example

This example is in Next.js and using the REST API but the logic should work the same with whatever technology you are using.

First, we create a custom useUpdatedUidRedirect.js hook file that checks if the route exists in the link resolver and does the redirect to the correct page.

import { useEffect } from 'react'
import { linkResolver } from 'prismic-configuration'

const useUpdatedUidRedirect = (document, router) => {
  useEffect(() => {
    const route = router.asPath.split('/')
    const uid = getUidFromRoute(route)
    const urlParams = getParamsFromRoute(route)

    if (document.uid !== uid) {
      const forwardUrl = `${linkResolver(document)}${urlParams}`
      router.replace(forwardUrl)
    }
  }, [document])
}

const getUidFromRoute = (route) => (
  route[route.length - 1]
    .replace(/#.*$/, '')
    .replace(/\?.*$/, '')
)

const getParamsFromRoute = (route) => {
  const pageRoute = route[route.length - 1]
  if (pageRoute.includes('?')) return `?${pageRoute.split('?').pop()}`
  if (pageRoute.includes('#')) return `#${pageRoute.split('#').pop()}`
  return ''
}

export default useUpdatedUidRedirect

Then in our dynamic [uid].js file, we do a few things:

  1. Import the useRouter function from next.js router.
  2. We import our custom useUpdatedUidRedirect hook.
  3. Call the router.
  4. Create an if statement to return 404 if the document doesn't exist.
  5. Call the useUpdatedUidRedirect hook and pass it the document and router.
  6. In the getStaticPaths function we set fallback: true so that the check is run if the UID is not found.
import React from 'react'
import DefaultLayout from 'layouts'
import { Header, SliceZone } from 'components'
import { queryRepeatableDocuments } from 'utils/queries'
import { Client } from 'utils/prismicHelpers'

import { useRouter } from 'next/router'
import useUpdatedUidRedirect from 'utils/hooks/useUpdatedUidRedirect'

const Page = ({ doc, menu }) => {

  const router = useRouter()

  if (!doc) {
    return null
  }

  useUpdatedUidRedirect(doc, router)

  if (doc && doc.data) {
    return (
      <DefaultLayout>
        <div className="page">
          <Header menu={menu} />
          <SliceZone sliceZone={doc.data.page_content} />
        </div>
      </DefaultLayout>
    )
  }

  // Call the standard error page if the document was not found
  return null;
}


export async function getStaticProps({ params, previewData}) {
  const ref = previewData ? previewData.ref : null

  const client = Client()

  const doc = await client.getByUID('page', params.uid, ref ? { ref } : null) || {}
  const menu = await client.getSingle('menu', ref ? { ref } : null) || {}
  
  return {
    props: {
      menu,
      doc,
      preview: {
        activeRef: ref,
      }
    }
  }
};

export async function getStaticPaths() {
  const documents = await queryRepeatableDocuments((doc) => doc.type === 'page')
  return {
    paths: documents.map(doc => `/${doc.uid}`),
    fallback: true,
  }
}

export default Page

Let me know if this is clear or not. I will begin working on adding this to our Next.js example projects. I'm not sure if I should add it to the documentation though, maybe just here works, what do you think?

1 Like

That's what I was saying in my original post of this thread was the only current option I could find. I suppose I wasn't clear there that of course I'd use a statically generated page if the current UID was asked for, and only query if an unknown one is given.

I don't like it. It means redirections are slow, and also that your API gets hit on every legitimate 404. I suppose some caching could be added, but it's still a kludge, and a lot of code to boot.

You clearly have the data somewhere; it'll be good once you add it to document metadata retrievable via the APIs.

Yeah I agree, this is only a workaround and like you said it has it's issues. I've passed this request to the devs and hopefully it's something they can start looking at soon.

2 Likes