Vue Watchers and SSR

Published 2 February, 2019

2 minute read

I have a little bit of code that handles the mobile menu on this site. It needs
to modify the body to add an overflow-hidden class from Tailwind. You can't
touch the body with reactive data in Vue, so you're stuck calling regular
browser APIs.

Completely forgot that document wouldn't be available during server-side rendering. It's ugly, but if you're gonna use a watcher, with immediate: true, you're gonn have to give up on that in favor of doing janky stuff in your mounted() hook. It isn't ideal (and if anyone has a better option, hit me on on Twitter), but I settled on this.

methods:{toggle(){this.open =!this.open
},addOverflowHidden(){
document.body.classList.add('overflow-hidden')
document.body.classList.add('scrolling-auto')
document.body.classList.add('fixed')
document.body.classList.add('pin')},removeOverflowHidden(){
document.body.classList.remove('overflow-hidden')
document.body.classList.remove('scrolling-auto')
document.body.classList.remove('fixed')
document.body.classList.remove('pin')}},// better to break it out into its own function, I supposemounted(){this.removeOverflowHidden()}

Pretty icky-feeling, but it works. Gonna roll with this for now.

Update: 2019-02-02

Turns out, you can access Gridsome's isServer clientAPI context property with
process.isClient, so you can still use watchers the way they are meant to be
used pretty easily. My current implementation looks like this.