2
votes

So I am using vuetify with "baseline" layout (from the documentation : https://vuetifyjs.com/en/examples/layouts/baseline). I set one page as pre rendered with :

  configureWebpack: {
    plugins: [
      new PrerenderSPAPlugin({
        // Required - The path to the webpack-outputted app to prerender.
        staticDir: path.join(__dirname, 'dist'),
        // Required - Routes to render.
        routes: [ '/about' ],
      })
    ]
  }

The page generated is fine. I made a compare with the html content from SPA and it's the same. However when the web server use it, the menu doesn't work. It's like the js is no executed to attach event to the elements.

The point is even if I take the content of the spa page and I copy past it in a page it doesn't work. I really dont get it. And I have no error in my debug console :-(

If anybody is inspired ? Or a process to analyse more deeply the issue.

Thanks a lot

2
Try adding data-server-rendered="true" to your root app element. See: github.com/chrisvfritz/prerender-spa-plugin#vuejs-notesLee

2 Answers

2
votes

TL;DR

index.html contains root element with id="app":

<body>
    <div id="app"></div>
</body>

main.js mounts your vuetify app into the root element:

new Vue({
    router,
    render: h => h(App)
}).$mount('#app');

App.vue - you need to wrap your app in element with the same id="app" as in the index.html:

<template>
    <div id="app" data-server-rendered="true">
        <v-app>
            ...
        </v-app>
    </div>
</template>

Why?

When you mount Vue app into root element by calling .$mount('#app') you actually replace the root element with your app.

Therefore before prerendering your index.html looks like:

<body>
    <div id="app"></div>
</body>

and after prerendering like:

<body>
    <div data-app="true" class="application theme--light">
        ...
    </div>
</body>

Then, when JS is loaded, it can't mount the Vue app because there is no #app element anymore, so you see that the page looks well, but nothing works properly, because JS isn't actually mounted.

So, if we wrap our app in an element with the same id as the root element in the index.html we can re-mount Vue app multiple times because the root element <div id="app"> is replaced with <div id="app">, so #app doesn't disappear after prerendering.


This is how I wasted 4 hours of my life...

0
votes

I was almost switching away to full SSR when I found Groxan's answer. BTW, setting id="app" to the <v-app> tag (as opposed to wrapping it with another div) also worked in my case.