Issue with meta tags for children routes, rendered via router-view, not being set on server side

725 Views Asked by At

TLDR: Pre-rendered views of child-routes are using the parent meta info, but I'd like them to use the meta info defined on the child-route component.

I've got a Nuxt/Vue site set up that has a landing page, /items/index.vue that provides a grid of items, and child-routes set up as children to that landing page in my router.js file. These child-routes are rendered as modals within the /items/index.vue via the nuxt-child or router-view components. The child-route calls a component called /components/ItemsModal.vue which sets the appropriate meta tags (title, og:data, ect)

When I enter the URL for a child route, the meta/head info updates as expected, after an initial flash of the parent /items/index.vue meta info. However, my SEO info is showing the parent meta/head info, and not the updated info that is defined by the child-route component. When I view-source, I see that the pre-rendered delivered page does indeed have the parent info, and not the child-route info, nor any of the content associated with the child-route component.

Anyone have any experience configuring child routes to pre-render with the head info defined in the child-route component? I would expect a child-route to render its associated component before calling it good on the pre-render.

Code below, truncated/modified for clarity.

router.js

{
    path: '/items',
    name: 'item-index',
    component: ItemIndex,
    children: [
      {
        path: ':slug',
        component: ItemModal, // defined as a var earlier in file
        name: 'item-modal'
      }
    ],
    alias: []
  },

/item/index.js

<template lang='pug'>
  ThePage
    ItemGrid
    nuxt-child
</template>

<script>
import ItemGrid from '~/components/ItemGrid'
export default {
components: {
  ItemGrid
}
head() {
  return {
    title: 'Parent Title,
    meta: [{
         hid: 'description',
         name: 'description',
         content: 'Parent description'
    }]
  }
}
</script>

/item/index.js

<template lang='pug'>
  ThePage
    Item
</template>

<script>
import Item from '~/components/Item'
export default {
components: {
  Item
}
head() {
  return {
    title: 'Child Title,
    meta: [{
         hid: 'description',
         name: 'description',
         content: 'Child description'
    }]
  }
}
</script>

1

There are 1 best solutions below

0
On BEST ANSWER

I neglected to mention that I was using vue-portal to lift the modal up in the DOM, and discovered, by more fully reading the documentation. SSR and Vue-Portal aren't compatible.

What I ended up doing was bypassing the vue-portal on SSR, just using nuxt-child to load the modal, and then triggering the vue-portal implementation on mounted. The SSR meta contact is properly handled through nuxt-child, and the UX is proper on mounted on the client side.