Dynamic route with route resolver not working properly

I'm trying to create a dynamic path for my posts with the new route resolver (yes, slice machine is activated). I have used these docs for the route resolver and I'm using exactly the same setup.

The problem I'm having is that the category part (example 3. With a Parent) doesn't really work properly.

As you can see below, the url should be /en/hello-world/the-post. hello-world is the category and the-post the post uid. The url does work, but so does for example /en/jdhfjks/the-post. So the category isn't really defined.

doc

And as you can see in the data section, it does recieve hello-world as parent uid.

doc2

This is my route:

{
   type: 'post',
    path: '/:lang/:category/:uid',
        resolvers: {
            category: 'category'
        }
}

And I'm using the nuxt-multi-language-site, the only difference is that I also have a dynamic _uid.vue file for the post. Which is in ~/pages/_lang/_category/_uid.vue (with a _category.vue import in the root of pages).

Can you help me figure out why I can type in anything in the category part and it works? This shouldn't be the case.

Hello Julian,

Thanks for reaching out to us.

I'd be happy to troubleshoot this. Can you please share the git hub repo with me? You can send me a private message.
Meanwhile, you can have a look at this thread, perhaps It helps:

Thanks,
Priyanka

That thread did not make me any smarter :slight_smile:

I got your DM. I'll take a look and get back to you. Thanks.

Hello @juliandreas,

I couldn't run your project because It was throwing an error, though, I'm providing this answer based on the folder structure and by looking at your .vue files.

It happens because when the control goes to level /pages/_lang/_category/_uid, all the variables are passed in params and flow goes to last .vue file, In your example case, /en/hello-world/the-post, the control will go to /pages/_lang/_category/_uid level and it will check for _uid.vue file for templating. In the code, you are trying to fire query on post uid, it means the-post. Notably, it does not check the category here, which can be anything.

Two approaches can solve this:

  1. When you go to level /pages/_lang/_category/_uid, you get the parent id (category-uid) in the document object (referring to your sample code snapshot in the question), and the same you can also get as part of params map. For example in /en/hello-world/the-post, you get the params map as {lang: 'en', category: 'hello-world', uid: 'contact-us' }. You can check if the category-uid and param.category are the same. If not, it should throw 404, as the URL is not correct.
    Note: I hope you have only one content relationship present in the post-id page, else you may need to apply loop for verification.

  2. Fix/Hardcode the category part instead of variation for example: /pages/_lang/{category-name}/_uid, and for each of the category, you need to have all the category levels in the hierarchy. As result, all post uid pages, which belong to the same category will fall under the same level.

Please let me know your thoughts or else we can work together to solve this.

Thanks,
Priyanka

Yes, sorry about that. But I did PM you the fix for it, it was just a small error.

  1. Do you mean I should query the post with the category params? I'm not quite following how you want me to solve this. (And yes, I have only one content relationship present).

  2. Hardcoded is unfortunately not an option.

Hello @juliandreas,

Here is the code snippet example to be used, when you get the ‘post’ response through prismic in /pages/_lang/_category-name/_uid.vue:

const post = await $prismic.api.getByUID('post', params.uid, lang);

//Here we are checking if the category from the url is the same as uid in our content relationship of post

 if (post && post.data.category.uid === params.category) {
   console.log('category available and control the usual code flow here');

//please add your code when category is found, ex: /en/hello-world/the-post, , and hello-world category is uid for content-relationship of the-post.

  } else {
    console.log('handle 404 because the category is not available');

//please add the code when category is not found, /en/xyz/the-post, and xyz category is not uid for content-relationship of the-post.
}

I hope this gives you a better understanding. Let me know if you have any doubt.

Thanks,
Priyanka

The console.logs are working! But how do I make it work in the end so that only the correct url shows a post?

I added this code and It's working:

1 Like

Thank you Priyanka, this works!

One issue though. Links to the post return not-found. So it seems as if I need both the Route resolver in nuxt.config.js and the link-resolver.js for my case?

I tried adding:

  if (doc.type === 'post') {
    return `/${doc.lang}/${doc.data.category.uid}/${doc.uid}`;
  }

.. to the link-resolver.js, but it returned Cannot read property 'category' of undefined.

So my question is, do I have to solve this with the link-resolver? And if so, what should be the correct return here?

By the way, my impression was that the link-resolver would not be needed when using the route resolver.

1 Like

I solved this with:

if (doc.type === 'post') {
    return '';
}

But in your route resolver docs, you're saying If it returns null for that document then it calls the Route Resolver.. Null doesn't work though, it just returns an error.

Hello @juliandreas

Currently, with the default behavior of link-resolver we can only deal with the 2 levels for any link: one with the first parent after root, and the second the last level of link. For example: in case of /en/hello-world/the-post, we can only get en and the-post in link-resolver.

Root Cause of null error:
After looking deeply in your code, there is no need to pass empty string. Rather, the null error comes because of the footer links, where in SiteFooter.vue file, same page link is used to be translated in all of the alternate languages of the site. There, you are explicitly calling link-resolver for the same.

Solution for handling it in Link-resolver:

You can handle it by looking at the following steps:

  1. We can pass category value as a parameter (named it as categoryUID) from /pages/_lang/_category-name/_uid.vue by adding it to the array object (alternate_languages). You are passing this array object to SiteFooter.vue and SiteHeader.vue file. Please refer to /pages/_lang/_category-name/_uid.vue templating like (<SiteFooter :alt-langs="altLangs" :content="footerContent"/ >)

  2. Look at the code in SiteFooter.vue file line 8 (<nuxt-link: to="$prismic.linkResolver(altLang)"), where you pass the individual element (altLang) of the array object in step 1.

  3. Please change the code for additional parameter in link-resolver.

I am attaching the modified files (/pages/_lang/_category-name/_uid.vue: Line 28) and (app/prismic/link-reolver.js: Line 23-25) for your reference.

Let me know if you have any doubt.

Thank you,
Priyanka

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