Get all old UIDs associated with a given document

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

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.

We recently had an issue with this.

We decided to create a new document type and manually migrate from the old to the new.

We were unaware that one document had an "old" UID, since this was not discoverable anywhere within Prismic. When we migrated, we made sure all documents were migrated by looking at the documents in Prismic, but because the old UID was not discoverable anywhere, this was missed. Traffic hit the old UID resulting in 404 errors and it took us some time to get to the bottom of the issue.

It should be possible to find alternate UIDs for a document because as-it-stands, they're effectively "secret" unless you already know they exist.

Thanks :slight_smile:

Hi Eilidh,

I know how this can be time-consuming as a process and hopefully, the team will be able to look into this issue soon.

I know this is on their radar but it's not currently being worked on. If/when this changes the team will update everyone here.

Thanks.