NextJS complex routing & language support

Hi, I followed the example from here to achieve grandparent/parent/doc path. The problem i have is that I also need to integrate language support in metadata. The docs in the alternate_language parameter only include the uid, but not the grandparent/parent in the same language. One solution - though quite a costly one - would be to fetch each alternate_language doc, but i was hoping there is more elegant way by enhancing the parameters that are returned in each alternate_language doc. Does anyone already have a solution?

Thanks in advance,
Peter

1 Like

Hi @peter2 ,

Thanks for this question. To make sure I understand, let me see if I get the basic issue. You have pages with grandparent/parent/doc paths, and you need to easily get the translated route. Is that correct?

Sam

In essence, yes. As an interim solution I did what i said to do as a dirty work around - here is the snippet from part of the code within getStaticProps:

let response = await Client().getByUID('posts', uid,
    { lang: 'en-gb', fetchLinks : ['category.display_name', 'category.section', 'section.display_name'] });

  if (response) {
    let altLangDocIds = [];
    response.alternate_languages.forEach(lang => {
      altLangDocIds.push(lang.id)
    })
    let docs = await Client().getByIDs(altLangDocIds, {lang: '*'});
    response.alternate_languages = docs ? docs.results : []
  } else response = null
1 Like

I had a similar issue here.

I ended up doing a costly fetch on getStaticProps and created a new object to give to my layouts and language switchers

  // fetch alternate categories slugs
  var alternativeLang = [];
  await Promise.all(
    doc.alternate_languages.map(async (lang) => {
      const fetchLang = await client.getByID(lang.id);

      alternativeLang = [
        ...alternativeLang,
        {
          id: lang.id,
          uid: lang.uid,
          type: lang.type,
          url: `/${lang.lang}/blog/${fetchLang.data.category.uid}/${lang.uid}`,
          category: fetchLang.data.category.uid,
          lang: lang.lang,
        },
      ];
    })
  );

Edit: it is costly but since it's on GetStaticProps it's handled asynchronously from the user so it's not that big of a deal

Hi @peter2 and @DavidParys,

Thanks for the detail. I've submitted an issue with our dev team, and I'll let you know what I hear back.

Sam

This thread is being monitored as an open ticket in the issue tracker. We will update this post as we get more information. If you have a similar use-case, you can ‘Flag’ this topic to reopen.

Is there any update on this issue? Having the exact same issue on my project. It would be really nice if for example the url is also provided (when you have a route resolver) in the alternate_languages array.

Roef-Jan

Hello @roelfjan

There is no update for the moment. You cannot do that using the route resolver for now. It would be best if you used the linkResolver function. Although I have sent a reminder to the team, I will return to you if I hear anything from them. I don't have ETA.

Thanks,
Priyanka

Thanks for you fast response!

How would that work with the linkResolver? My Route Resolver is this:

    {
      type: 'contentpage',
      path: '/:lang/:grandParentPage?/:parentPage?/:uid',
      resolvers: {
        grandParentPage: 'parent.parent',
        parentPage: 'parent',
      },
    },

The parent property is also of custom type contentpage. So I can create urls like /[lang]/foo/bar/baz, which are nestes contentpages.

I now fixed it on the server by first getting the contentpage by using getByUID and after it getting the documents of the alternate_languages of that page by using getAllByIDs. This gives me the document with the url property.

Hello @roelfjan

Unfortunately, it’s not possible to do more than one level deep of nested threads at the moment.

But I can think of one approach. For achieving nested levels in conentpage, You can define two content relationships there, one for grandParentPage and one for parentPage. That way, you can use these content relationships for generating URLs.

And code example will be something like:

if (doc.type === 'contentpage’){
  if(!${doc.data.[PATH-TILL-PARENTPAGE-IN-CONTENT-RELATIONSHIP]}){
    return `/${doc.lang}/${doc.data.[PATH-TILL-GRANDPARENTPAGE-IN-CONTENT- RELATIONSHIP]}/${doc.data.[PATH-TILL-PARENTPAGE-IN-CONTENT-RELATIONSHIP]}/${doc.uid}`
  }
} else{
    return `/${doc.lang}/${doc.data.[PATH-TILL-GRANDPARENTPAGE-IN-CONTENT-RELATIONSHIP]}/${doc.uid}`
  } 
}

Please note you may be required to change the code snippet according to your need. I only considered grandparents and parent level here.

Let me know if you have any further questions.

Thanks,
Priyanka

Thanks for you suggestion. My code block in my previous reply is already solving the same which you are solving a bit different in your code block.
The problem is, this doesn't work for the alternate_languages of a page. The Prismic API only returns id, lang, type and uid. So doc.data isn't present. It would be nice if the Prismic API added the url property as well, when you have a Route Resolver. Hopefully it can be added to your backlog!

Hello @roelfjan

I gave you a code block to use link resolver. It's true that Route Resolver doesn't work for the alternate_languages of a page. We are already tracking it as a feature request. Thanks for showing your support for this.

Priyanka

2 Likes

The work around using nested queries takes a lot of time and drags down the SEO value of a page - meaning it's less like a page will be ranked high and shown by any search engine.

Anyone that builds a multi-lingual website that is SEO tuned will have a need for such a feature. If you are in the same bucket, please show your interest by clicking on the :heart: - otherwise Prismic will less likely consider any change.

1 Like

this code doesn't work for me since linkResolver function doesn't have a data object or is there a workaround????

Hello @loudmu

Would you please elobrate on your use-case?

Thanks,
Priyanka

hi Priyanka,
my use case is the same as the one described by [roelfjan] .
also as per your documentation Link Resolver and Route Resolver - Prismic,
the Route Resolver is the only to build complex URLs based on Content Relationships.
so a solution as suggested by peter is urgently needed as our use case is very common

Thanks for sharing your use case @loudmu. At the moment, the Link Resolver doesn't allow this kind of nested URLs. We're currently discussing adding more complexity to the route resolver, but it is still a work in progress. You can follow updates on any changes on our progress page: What's new - Prismic

Just to avoid that this request gets side-tracked: To create a complex routing with 2 or more levels without SEO support is already doable. The seemingly best approach is indeed to create two relationships between the document and the parent as well as grant-parent - or 3 relationships if you have also grand-grand-parents. For this, you will not need any additional api query. I believe, @Priyanka referenced this solution before even though I didn't need her code example for the Link Resolver. I only use the Route Resolver for this purpose.

My issue however is that to support complex routing on a multi-lingual website, you end up making more sequential api calls to retrieve all data. In my case, I have 2 separate calls in sequence (one for the main doc, the other one to retrieve all alternate language docs). I have a few more API calls for the page for related blogs, most read blogs, and so on, but that's a different story. Long story short, it takes about 28 secs to render a single page and pages that don't have to make those many calls only take about 8 seconds. I need ti mostly for SEO and because of this, all pages are ISR rendered. Therefore the user doesn't see anything of the 28 secs, but it's a high cost during build. As Prismic claims it supports complex routing with language support, this is a gap that has been overlooked and should be supported. But again, work-arounds are available.

Hi Peter,
Thanks for your approach to this.
Choosing this one as well, but looking forward to a native implementation of the url property on the altlangs when using the route resolver.
Cheers,
Mike