Search code examples
node.jsvue.jsvue-componentvue-routervue-ssr

Vue SSR serverPrefetch server redirect with this.$ssrContext.res.redirect


Is it possible to do a redirect from a component, in VUE SSR, without getting the error on the server console: [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client?

Code is as follows:

serverPrefetch() {
    // need the data from this.fetchPage service to decide on the redirect
    return this.fetchPage().then(function (response) {
        // do some checks here

        // THIS IS THE NODE EXPRESS REDIRECT
        this.$ssrContext.res.redirect('/');
        this.$ssrContext.res.end(); // with or without, same error
    }.bind(this));
},
beforeMount() {
    this.fetchPage();
}

NOTE: If I try to use this.$router.replace('/') (or any other methods), I get the error: [Vue warn]: Error in callback for watcher $route: ReferenceError: document is not defined.

In my project I did the redirect on the client side, but I was wondering if this can be done also from server.


Solution

  • TL;DR:

    Reject the serverPrefetch with {url: '/redirect-route'}

    Found the solution as follows: If you implement the vue-ssr project as the https://github.com/vuejs/vue-hackernews-2.0 repo, in server/index.js you have a handleError function that has a redirect in it:

    if (err.url) {
            res.redirect(err.url);
        }
    

    And all you need to do in your component is:

    serverPrefetch() {
        return this.fetchPage().then(res => {
            if(res === 'MY_REDIRECT_CONDITION') {
                // !!! THE ACTUAL REDIRECT TRIGGER !!!
                return Promise.reject({url: '/'});
            }
    
        });
    },