0
votes

I got the following setup in pages

/pages/index.vue
/pages/_blog
/pages/_blog/index.vue
/pages/_portfolio/
/pages/_portfolio/index.vue

The blog and portfolio are dynamic as the user the CMS should be able to change them for example make portfolio to myportfolio

So I link in nuxt as follow

<nuxt-link :to="{name: portfolio, params: {portfolio: 'myportfolio'}">portfolio</nuxt-link>

So far so good! When clicking on the link you will go to the portfolio and it wil use the page portfolio component.

However when I refresh/reload. I'll get the page blog component. Hence when reloading the param is not passed and so it does not know what page component it should us. I guess it takes the first it finds in this case the blog component.

I don't find any documentation how to handle this. If the structure would be more simple example

/pages/index.vue
/pages/blog/index.vue
/page/portfolio/_slug.vue

Then it kind of simpler. As the params will be a the slug and component always portfolio. But in my case the subroot components are already dynamic.

So my question. How do make NUXT understand that in case of http://localhost:3000/myportfolio/ the component portfolio should be used. I can determine from my Wagtail api the type of page, slug, id etc... So this should not pose a problem. But to do this I need first to have the correct component.

thx in advance for help!

1

1 Answers

0
votes

You're going to need to use unknown dynamic nested routes, and possibly nuxt-child components.

/pages/index.vue
/pages/_.vue

Note: Handling 404 pages is now up to the logic of the _.vue page.

Now, any route that is not handled already will be handled by the _.vue component.

This is going to require some handling logic in _.vue to get the page switching right. I would highly recommend looking at this example, which deals with using nuxt-child in page components.

Another way to implement this behaviour is using Vue's dynamic components. For example, something like this may work:

~/pages/_.vue

<template>
  <component :is="component" :data="component_data" />
</template>
<script>
import Portfolio from '~/components/Portfolio'
import Blog from '~/components/Blog'

export default {
  computed: {
    component() {
      switch(this.component_name) {
        case 'portfolio':
          return Portfolio
        case 'blog':
          return Blog
      }
    }
  },
  async asyncData({ route }) {
    // accessing /myportfolio/portfolio will result in
    // route.params.pathMatch to equal /myportfolio/portfolio
    // which can be used to fetch API data
    return {
      component_name: 'portfolio',
      component_data: 'fetched_from_api'
    }
  }
}
</script>

I've omitted a lot of the details here, but the basic premise is using _.vue as a catch all, fetching your API data and determining the component dynamically, and rendering out that component.

I'd recommend reading through the links I posted and trying them out to see what will work for your use case, and updating with more specific information if these don't work.