Nuxt with SM Routes

I am having issues getting my route resolver settings to work. I have multiple page types that I want to generate to the following routes: /home/subpage. This is my config:

"apiOptions": {
        "routes": [
          {
            "type": "pagev2",
            "path": "/:uid"
          },
          {
            "type": "subpage",
            "path": "/:subpageparent/:uid",
            "resolvers": {
              "subpageparent": "subpageparent"
            }
          },
          {
            "type": "subpagerightrail",
            "path": "/:supagerightrailparent/:uid",
            "resolvers": {
              "subpagerightrailparent": "suppagerightrailparent"
            }
          }
      ]}

In both custom types I have a content relationship field that points to the home page of my site. My filesystem structure is set to this:

+ pages (folder)
-  _uid.vue
-  -  +  _subpageparent (folder)
-  -  -  +  _uid.vue
-  -  + _subpagerightrailparent (folder)
-  -  -  +  _uid.vue

When I run this, the routes are correct but it always uses the first page type, so the page built on the other page type breaks. Seems to always default to the first /_folder/_uid.vue that is finds. Am I setting this up wrong?

I'm starting to understand why this doesn't work and why it always goes to the first dynamic folder it finds. If anyone knows how I can manage this to make it work, any help would be appreciated.

Essentially what I'm trying to do is create a route structure that is /_siteroot/_subpage/, but the subpage can be different page/document-types. This site is actually going to house multiple small micro sites, so there will be multiple "/_siteroot/"s and then subpages under them. I currently have this working, but I have to use the same document type for all subpages to make it work currently.

Hello,

Thanks for reaching out.

I'd be happy to troubleshoot this. For this, can you please send me github repo and url of your repository? If you do not want to send it publicly, you can send me a private message.

Thanks,
Priyanka

Hello Shawn,

Thanks for posting us.

The following approaches possible in this case:

  1. Validate the response returned by each level using this. For ex:
    if route at "/:subpageparent/:uid" returns 404, then move to next route which is "/:supagerightrailparent/:uid" , and the same is repeated until it finds the expected response.

But, in case of multiple sites, it is not recommended to use this solution, because there may be lager number of queries triggered here.

  1. Next approach can be to hardcode one of the level. For ex: instead of "/:subpageparent/:uid" , use "/subpageparent/:uid" , so hardcoding "subpageparent" , and use it as fix folder name by removing wildcard( _ )
  2. Another approach is to have a fix folder name in all paths such that no two wildcards can have the same level. For ex: instead of "/_subpageparent/_uid" , use "/{name1}/_subpageparent/_uid" , and the same for other paths "/_supagerightrailparent/_uid" , use "/{name2}/_supagerightrailparent/_uid ".
    Here you can have different folder names in place of {name1} and {name2}

Please let me know if you have any other doubt.

Thank you,
Priyanka

Thank you for your response. I really don't want to hardcode layers into my route, I would like like to keep it dynamic. I don't think using the "validate method" would be so bad if I could just validate the document type instead of the ID, but currently I only have the ID available on the initial response. Is there a way to validate the document type at that time?

Ran into another issue that is related to this one. As I stated, I'm going to have multiple small sites in this repo and I'm setting up dynamic routing such as "/:site-root/:pageuid". I just realized that if I am creating these page documents in Prismic, UID has to be specific and it used for the URL, but I am going to have multiple pages in the site that may need to have the same subpage url, such as a "contact-us" page.

ex1: https://localhost:3000/site1/contact-us
ex2: https://localhost:3000/site2/contact-us

Obviously I can't give both subpages the same ID of "contact-us". If I made the UID something like "mysite1--contact-us" and "mysite2--contact-us", is there anyway to strip the string at the "--" characters before nuxt builds the routes?

It would be nice if I could give them unique IDs and use a different field for the desired URL string.

Hey Shawn,

It sounds like your best bet here would be to have different custom types for different websites, like 'site-1-page' & 'site-2-page', that way each custom type could have a UID of 'contact-us' with no conflict. Plus this would make the route resolving issue easier.

You wouldn't really have to worry about maintenance either as with Slicemachine has shared Slices which are pushed to all custom types so they're easy to update.

Let me know what you think.

@Phil Yeah, not sure that solution will work for me. This repo will house about 38 micro sites in the end. Making 38 different custom types for each type that needs to share a similar url structure would be a lot of overhead and would defeat the purpose of being able to have content authors just create some new content to spin up a new site. I feel like there is a use-case here to be able to give a doc a unique id but use a different field to set the value used in the URL.

Also, I asked above if there is anyway to modify that UID before it passed into the route? Since you didn't mention that part, am I to take that to mean that it is not possible. (Speaking about the question: if I set the UID to something like "mysite--contact-us", is there any way to peform string manipulation on it on the application side to strip off the "mysite--" before it is passed to the route resolver?

edit: adding @alws just for more visibility. I'm so close to having a working solution for this project to show my leadership, so I would hate to have to drop this entire solution because I can't meet the routing requirements.

For 1st question:
You do not get the document type on hitting url, rather you can use the type in the respective _uid.vue. For example in "_subpageparent/_uid.vue" , you already know that the possible type would be of "subpage" for wildcard value in "_subpageparent" , so you have id and type both values in "_subpageparent/_uid.vue" .

Here is how you can get the param-id of "_subpageparent" in " "/_subpageparent" /_uid.vue" :

You get the id mapped with folder name like , on hitting URL "/subpageparent1/uid1" , you get all the ids in params map in "_subpageparent/_uid.vue" , like:
{ subpageparent: 'subpageparent1', uid: 'uid1' }
you can validate the id with request to type by querying the api with different custom types available in $prismic.api.types map.

For second question, you asked:

  1. Define content with UID like "mysite1--contact-us" and "mysite2--contact-us" in prismic.
  2. Define router in nuxt for "/:site/:uid" or "/:site/contact-us" (if you want to fix the uid).
  3. Define hierarchy like "/_site/_uid/_uid.vue" , in "_uid.vue" , you can get all params related to the route. for example: if the url is "/mysite1/contact-us" , then in params in "_uid.vue" file, you will have params map like:
    { site: 'mysite1', uid: 'contact-us' }

You can acess those values and make some string operations to get the desired uid pattern like applying "--" between both params values and it will be "mysite1--contact-us" , let's call it as concatenated_uid
4. Query the api "$prismic.api.getByUID( document.type, concatenated_uid )" and check the response.

I hope this answers your question and let me know if you have any doubt.

@Priyanka. On the second qestion, you kind of lost me in that last bit.

  1. That matches the UID structure I currently have in my docs
  2. That matches my current nuxt config route settings
  3. This is where I get a little lost in your explanation. The problem is the route is = '/mysite1/mysite1--contact-us' because I have to give the doc a unique id in prismic and I need to make it '/mysite1/contact-us'. I am also using slicemachine so this is all happening automatically. Are you saying I can take over the query in the _uid.vue file and do it manually to reset the url? Isn't the route/url already set by the time _uid.vue comes into play?

Hey Shawn,

I'm going to check this with our development team to see if they have any ideas to resolve this. I'll come back to you ASAP.

Thanks,
Priyanka

Did the development team have any recommendations on this?

Hey Shawn,

No recommendation yet, and I've already sent a message yesterday to follow-up.

Thanks

Hello @arcaneshawn,

I hope you are doing well!

I apologize because I didn't come to you with the solution. I'm going to submit this in the issue tracker. I'm curious to know, were you able to manage this?

Priyanka

Hello @arcaneshawn,

I have discussed this with our dedicated developer. Here are some bits to help you on that one:

Mapping URLs:
If you are using the apiOptions.routes feature that is not able to do that kind of programmatic parsing, unfortunately. I'd recommend using a link resolver here, something like that:

// linkResolver.js
module.exports = doc => {
  const [site, uid] = doc.uid.split("--");

  switch(doc.type) {
    case "page":
      return `/${site}/${uid}`;

    default:
      return "/";
  };
};

Querying the right UID:
Here I'd suggest leveraging Vue router params to resolve the UID and query the right document:

// ~/pages/mysite1/_uid.vue
export default {
  async asyncData({ route }) {
    const site = route.path.split("/").filter(i => !!i)[0];
    const resolvedUid = `${site}--${route.params.uid}`; // e.g. "mysite1--contact-us"
    /* ... */
  }
};

Give this a try and let me know.

Thanks,

Priyanka

1 Like

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