Dynamic nuxt routing with legacy fallback

How do I configure nuxt and layer0 routing so that I can render a dynamic page with an arbitrary path and then fall back to legacy if there are no matches?

I am querying contentful for a list of slugs and want to render nuxt pages if the URL path matches a contentful slug and fall back to legacy if not.

I suggest implementing this logic entirely in Nuxt. Attempt to fetch from contentful in your page’s fetch hook, and if no match is found. So something like:

<script>
export default {
  fetch ({ redirect }) {
    const res = await fetch(contentfulURL)
    
    if (res.status === 404) {
      return redirect('/404')
    }
  },
}
</script>

@mark.brocato are you saying we would need to declare the proper legacy fallback route in that redirect method (part of nuxt context), and that would pass through to the layer0 router? Or is this avoiding that router file altogether?

@christooma I recommend that you get the dynamic routing based on contentful slug functioning in Nuxt and then we’ll add in the fallback to legacy

@mark.brocato here’s how we query contentful in a pages/_slug.vue file. getPageBySlug is a custom method in our contentful plugin that watches the slug in the URL and tries to run a contentful query on it. The big issue (and the reason for this post) is that we can’t accurately fallback to legacy because every route is open to hitting nuxt first (because of the wildcard _slug.vue) file. Trying to manually extendRoutes() with a list of known contentful pages also fails because asyncData never reruns when the same page component is called (all of those known contentful routes are using the same _slug.vue file) so you end up with the slug changing in the browser URL, but the content never refreshes.

Maybe you’re suggesting we use fetch() since it can be manually refetched as a method?

 async asyncData({ $contentful, error, store, route, params }) {
    try {
      const page = await $contentful.getPageBySlug(
        store.state.previewMode,
        slug
      );

      return {
        page,
        activeSlug: route.path
      };
    } catch (err) {
      error({
        // ToDo: proper error page (the error could be other than a 404)
        statusCode: 404,
        message: err.message
      });
    }

@christooma try something like this:

new Router()
  .get('/fallback', ({proxy}) => proxy('legacy'))
  .use(nuxtRoutes)
////// Nuxt //////
/pages
  /[...slug].js
<script>
  fetch() {
    const res = await fetch('/cms')
    if (res.status === 404) {
      redirect('/fallback')
    }
  }
</script>

if the contentful page is not found, redirect rather than 404.

then the route for that fallback redirect proxies legacy