What should a link resolver do when a document type sometimes doesn't have a page?

I have a document type which sometimes has a page and sometimes does not, and this depends on whether it is tagged with a particular tag or not.

In my application code I can easily check for this tag and render a link or not as appropriate when I'm looping through documents of this type.

I can do the same in my custom HTML serializer to cover the case where links are in rich text, though this would be a pain if I didn't already have my own HTML serializer.

That made it occur to me that it doesn't look like there's any built-in support for this use case. The typings for LinkResolver (in prismic-reactjs at least) say that it non-optionally returns a string, and the HTML serializer code doesn't check the link resolver's result, just goes ahead and throws it in the href attribute.

In other documentation you seem to have mixed conventions -- in this doc one example falls back to / and another falls back to /doc/<id>. But I want the hint to get to my application that it shouldn't render a link at all.

I think it would be good if link resolvers could return null (or undefined, whatever you prefer) in cases where there is no URL for that document. The SDK code should then support that and avoid rendering links as appropriate.

I think what I'll do for now is return the empty string and handle that specially in my codebase. I'll also need to tell my preview mode handler to handle that empty string and return the home page URL.

In fact it looks like I don't have to do anything special in the preview handler: the prismic-javascript preview resolver code will fall back to the default URL if the link resolver gives an empty string (or anything else falsy).

Hey @bart,

Thanks for all of the detail. I don't fully understand your use case and your info architecture, but I'll try to speak to the usage that you're discussing.

As you said, it's possible to render a link conditionally with the HTML Serializer, and that's what we recommend. Basically, it's the job of the HTML Serializer to decide what kind of element to render, and it's the job of the Link Resolver to route links. So, if you're trying to determine whether or not to render an <a> tag, we recommend using the HTML Serializer (the isBroken property on Link elements is useful for this). Then, the Link Resolver handles the route.

Note: You can pass a custom HTML Serializer as a prop to the RichText Prismic component in React. That needn't be a full HTML Serializer. It can specify how to handle a link of a certain type with a true isBroken property, and return null otherwise; the default HTML Serializer will take care of all other elements.

Otherwise, outside of a Rich Text field, you can use JavaScript to conditionally render a Link element based on isBroken , again without worrying about the Link Resolver.

I think part of the logic here is that we do not want the default behavior for a broken link to be no link. Generally, the default behavior should be a 404 (even thought that might not be the case in the examples you linked).

Having said all of this, I recognize that I might've misunderstood your use case. If so, please correct me! I love discussing use cases and edge cases.

Thanks,
Sam

Maybe it'd help if I gave a concrete example -- broken links aren't involved at all here.

In my data scheme we have a Person model. Its documents can describe blog post authors and members of the company. Not all blog post authors are company members, and not all company members are blog post authors.

All Person documents have certain fields filled in but only company members have their own page on the website.

Therefore the link resolver sometimes returns something like /person/<uid> for a Person document, and sometimes it shouldn't return a URL at all. I make the decision based on whether the document has a particular tag or not.

I think it'd be good if this use case were covered. I can imagine the standard procedure to be to return null for documents which should not be linked to, and then for the built-in HTML serializer to take that as "this document shouldn't have been linked to; I won't render a link".

Absolutely. As I hopefully explained better this time, in this instance the link resolver wants to say "even though this document does exist, there is no URL for this document", and I want the HTML serializer to notice that and say "fine, I'm rendering a span".

In my codebase I'm returning an empty string from the link resolver in these situations (rather than null, to keep Typescript happy), and handling it in my custom HTML serializer. Perhaps it's not a common enough use case to handle in the SDKs.

Oh wow! Thanks very much for the example — that really helps.

Based on what you've said, I think we would still recommend handling this with the HTML Serializer. If you're tagging documents, and you want to render a link or not depending on the tag, you could include a simple HTML Serializer like this (forgive my janky pseudo code. I haven't tested it and it might not work as is.):

const linkResolver // define a linkResolver

const htmlSerializer = (type, element, content, children) => {
  if(type === "hyperlink"){  
    // check the tag on the linked document
    if (element.data.tags.includes("author")) {
      return `<a href="${linkResolver(element.data)}">${children.join('')}</a>`
    }
    else if (element.data.tags.includes("member")) {
      return `<span class="member">${children.join('')}</span>`
    }
  }
  return null
}

This principle could even extend to the content of the linked document, by using fetchLinks. You could, for instance, put a boolean field or a multi-select on the person document, with the options "person" and "member," and then fetch that field with fetchLinks. In your HTML Serializer, you could do something like:

if(element.data.data?.role === "member"){
  return "<span class="member">${children.join('')}</span>"
}

It's possible that my code snippets are buggy, or that I'm not understanding your usecase. I believe it's possible — and advantageous — to use the HTML Serializer to accomplish what you're trying to do. In any case, let me know what you think.

Best,
Sam

Yes, it's totally possible. As I said, I'm already handling it in my custom HTML serializer.

I was just wondering if it had been considered before (I don't much like that I have to return an empty string rather than a null), and hoping it might be something the SDKs might support out of the box in future.

Hey @bart,

I think I still don't understand your use case. If you're handling this with your HTML Serializer, why would you use the Link Resolver at all for members?

The Link Resolver is called inside the HTML Serializer. So why would you make the Link element conditional on the output of the Link Resolver, when you could handle the logic entirely in the HTML Serializer? In that case, the Link Resolver would never be invoked for a member.

I get the sense that I'm still missing a key part of this. Let me know!

Sam