Prerender vue application issue with prerender-spa-plugin

Viewed 181

I am trying to get prerender-spa-plugin to work. At the initial setup I was getting some errors, which turned out to be due to prerender-spa-plugin being incompatible with webpack 5. I then found a forked version of the plugin which works with webpack 5 (@dreysolano/prerender-spa-plugin).

The problem now is when I run npm run build, the folders are correctly created for each route, but the html just returns instead of the HTML for the specific route. (I have script tag in the index.html also, and all the css etc for that is prerendered, its just the content under #app that isn't)

This is my vue.config.js at the moment

const PrerenderSPAPlugin = require('./node_modules/@dreysolano/prerender-spa-plugin');
const {join} = require('path');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer

module.exports = {
runtimeCompiler: true,

publicPath: process.env.NODE_ENV === 'production'
    ? '/app/'
    : '/',

css: {
    loaderOptions: {
        sass: {
            additionalData: '@import "~@/styles/custom.scss";'
        }
    }
},
configureWebpack: {
    plugins :[
        new PrerenderSPAPlugin({
        staticDir: join(__dirname, 'dist'),
        routes: ['/'],
        postProcess(context) {
        context.html = context.html.replace('id="app"', 'id="app" data-server-rendered="true"');
        return context;
        },
        renderer: new Renderer({
        inject: 'head',
        renderAfterDocumentEvent: 'render-event'
        }),
        headless: true
        })
        ]
},
chainWebpack: config => {
    config.module
        .rule('vue')
        .use('vue-loader')
        .loader('vue-loader')
        .tap(options => {
            return {
                transformAssetUrls: {
                    video: ['src', 'poster'],
                    source: 'src',
                    img: 'src',
                    image: 'xlink:href',
                    'b-avatar': 'src',
                    'b-img': 'src',
                    'v-img': 'src',
                    'b-img-lazy': ['src', 'blank-src'],
                    'b-card': 'img-src',
                    'b-card-img': 'src',
                    'b-card-img-lazy': ['src', 'blank-src'],
                    'b-carousel-slide': 'img-src',
                    'b-embed': 'src'
                }
            }
        });
    const path = require('path')
    config.resolve.alias
      .set('AutoNumeric', path.resolve(__dirname,
        'node_modules/autonumeric/dist/autoNumeric.min'));
},

devServer: {
    proxy: {
        '^/api': {
            // target: `http://${process.env.BACKEND_HOST || 'localhost'}:5000/`,
            target: process.env.BACKEND_URL || 'http://localhost:5000/',
            ws: true,
            changeOrigin: true,
            pathRewrite: {
                '^/api': '/'
            }
        }
    }
},

pluginOptions: {
  i18n: {
    locale: 'en',
    fallbackLocale: 'en',
    localeDir: 'locales',
    enableInSFC: false
  }
}

}

I've tried renderAfterTime (not recommended) and no results. When I add:

renderAfterDocumentEvent: 'render-event'

the npm run build just runs forever, which is probably because no event is ever dispatched for some reason, even though I have added this:

new Vue({
router,
store,
axios,
i18n,
render: function(h) {
 return h(App);
},
mounted() {
// You'll need this for renderAfterDocumentEvent.
setTimeout(() => {
  document.dispatchEvent(new Event('render-event'));
}, 5000);
},
 }).$mount("#app");
0 Answers
Related