Previewing unpublished documents doesn't work with modified lang code

(I get the following issue with both gatsby-source-prismic-graphql as well as @prismicio/gatsby-source-prismic-graphql)

I have a multi-locale site and have had to convert the lang/locale code in URLs to country codes (actually a mix of country codes and lang codes, but for simplicity's sake and in my example project it's just country codes), so instead of /en-gb/my-page or /en/my-page, it would be /gb/my-page. It's not possible to achieve this with the plugin as it is, so I've had to hook into Gatsby's onCreatePage API and modify the path with a helper function like so:

exports.localeToCountryCode = localeCode => localeCode.split("-")[1].toLowerCase()

(this :point_up: is also used in the linkResolver)

Everything seems to work locally, in production and also when previewing published documents, but for some reason this seems to interfere with trying to preview unpublished documents.

My page query looks like this:

query($lang: String!, $uid: String!) {
  prismic {
    allPosts(lang: $lang, uid: $uid) {
...

It seems as though the lang variable isn't getting passed to the page query, since props.data.prismic.allPosts.edges is returning an empty array:

image

If I remove the lang filter from the query, I then get data returned and am able to preview unpublished documents. It also seems to work (even with the lang filter) if I don't convert the locale codes to country codes.

When clicking on the preview button, I am taken to http://localhost:8000/preview/post?lang=de&uid=mein-erster-beitrag, which I think is correct, as I believe this is the default preview path, plus the params with the correct locale and uid/slug as I've defined it in Prismic.

I've set up previews and configured my pages with the type, match and component properties:

{
  type: "Post",
  match: "/:lang/posts/:uid",
  component: require.resolve("./src/templates/post.js"),
}

You can find a reproducible test case here: GitHub - mrseanbaines/prismic-previews-multi-locale.

Hey Sean!

Previews and Gatsby plugins are currently having a difficult time, as we’ve mentioned in this article: Gatsby-Prismic plugins: what’s going on?. Many issues related to these plugins and the Preview feature will be difficult to solve at the moment. Please read: Using Prismic Previews with React

With drafts and published documents, the preview uses a URL that doesn’t require the full language code in it. For unpublished documents, the query value of the complete lang is required. You can verify it by removing the localeToCountryCode function from all links in your code, the preview works without problems.

The only quick fix I could find if you wanna continue having the lang set-up that you did with localeToCountryCode. is to manually add the missing lang value in the URL when doing a preview session.

So, for example, if you create a new doc in of the type Post, in the German locale, with the UID of “neuer”, and try to preview it you’ll get this route:

http://localhost:8000/preview/post?lang=de&uid=neuer

To fix it, just complete the lang code in the URL like so:

http://localhost:8000/preview/post?lang=de-de&uid=neuer

Thanks for the reply @Pau.

Unfortunately I don’t think the content team would be very happy with having to modify the URL params, and we need to keep the country codes. I’m not too opposed to refactoring though to achieve the same thing if you know of a better way to do this that doesn’t interfere with the previews?

Not sure if you saw in my example project, but it seems to work if I just don’t convert the locale in the link resolver file, so I think I can check for the existence of last_publication_date and if that doesn’t exist then I guess we know we’re dealing with an unpublished preview, so don’t convert the locale in that case:

const { localeToCountryCode } = require("./localeToCountryCode")

exports.linkResolver = doc => {
  // This seems to work but I don't know why... 🤔
  const localize = path =>
  `/${!doc.last_publication_date ? doc.lang : localeToCountryCode(doc.lang)}${
    path === "/" ? "" : path
  }`

  // const localize = path =>
  //   `/${localeToCountryCode(doc.lang)}${path === "/" ? "" : path}`

  switch (doc.type) {
    case "page_2": {
      return localize(`/page-2`)
    }

    case "post": {
      return localize(`/posts/${doc.uid}`)
    }

    default: {
      return localize(`/`)
    }
  }
}

…I’m not sure yet if this has any repercussions or not. Do you think this could break something else?

If using either this or the modifying URL params method to “solve” the issue, I ran into another problem, which is that I’m passing the locale as context which is used throughout the site for various things (e.g. localized links, SEO etc.), but I guess the preview script won’t be able to replace this value(?), so the only way I can think to get around it is to check the URL when the page loads to see if it’s a preview page and includes the lang param, and if so then pass that value to the context provider, but if not then use the one coming from the page context set at build time (as I normally would) - this also feels pretty hacky and not sure if I’ll run into issues with this approach. Do you have any thoughts/ideas on this?

Hey Sean!

What you did in the link Resolver does the trick in the same way as manually correcting the URL and as you say, it breaks all the other routes while on Preview, like the homepage.

I would try what you’re suggesting, seems like a workaround and a good solution since the plugin doesn’t offer any other option to shorten the lang codes.
langs other than the default shortenUrlLangs,

This issue has been closed due to inactivity.