title: how to use window.innerWidth within computed property - NuxtJS
body: <p>I'm working on a nuxt.js project, where I need to determine styles within the <code>computed</code> propety and apply on a <code>div</code> based on <code>screen size</code>, as in the example below:</p>
  
  <p>basic example</p>
  
  <pre><code>&lt;template&gt;
    &lt;div :style="css"&gt;&lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    computed: {
      css () {
        let width = window.innerWidth
  
        // ... mobile { ... styles }
        // ... desktop { ... styles }
  
        // ... if width is less than 700, return mobile
        // ... if width greater than 700, return desktop
      }
    }
  }
  &lt;/script&gt;
  </code></pre>
  
  <p>real example</p>
  
  <pre><code>&lt;template&gt;
    &lt;div :style="css"&gt;
      &lt;slot /&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    props: {
      columns: String,
      rows: String,
      areas: String,
      gap: String,
      columnGap: String,
      rowGap: String,
      horizontalAlign: String,
      verticalAlign: String,
      small: Object,
      medium: Object,
      large: Object
    },
    computed: {
      css () {
        let small, medium, large, infinty
  
        large = this.generateGridStyles(this.large)
        medium = this.generateGridStyles(this.medium)
        small = this.generateGridStyles(this.small)
        infinty = this.generateGridStyles()
  
        if (this.mq() === 'small' &amp;&amp; this.small) return Object.assign(infinty, small)
  
        if (this.mq() === 'medium' &amp;&amp; this.medium) return Object.assign(infinty, medium)
  
        if (this.mq() === 'large' &amp;&amp; this.large) return Object.assign(infinty, large)
  
        if (this.mq() === 'infinty') return infinty
  
      }
    },
    methods: {
      generateGridStyles (options) {
        return {
          'grid-template-columns': (options !== undefined) ? options.columns : this.columns,
          'grid-template-rows': (options !== undefined) ? options.rows : this.rows,
          'grid-template-areas': (options !== undefined) ? options.areas : this.areas,
          'grid-gap': (options !== undefined) ? options.gap : this.gap,
          'grid-column-gap': (options !== undefined) ? options.columnGap : this.columnGap,
          'grid-row-gap': (options !== undefined) ? options.rowGap : this.rowGap,
          'vertical-align': (options !== undefined) ? options.verticalAlign : this.verticalAlign,
          'horizontal-align': (options !== undefined) ? options.horizontalAlign : this.horizontalAlign,
        }
      },
      mq () {
        let width = window.innerWidth
  
        if (width &lt; 600) return 'small'
        if (width &gt; 600 &amp;&amp; width &lt; 992) return 'medium'
        if (width &gt; 992 &amp;&amp; width &lt; 1200) return 'large'
        if (width &gt; 1200) return 'infinty'
      }
    }
  }
  &lt;/script&gt;
  
  &lt;style lang="scss" scoped&gt;
  div {
    display: grid;
  }
  &lt;/style&gt;
  </code></pre>
  
  <p>making use of the <code>GridLayout</code> component on pages.vue</p>
  
  <pre><code>&lt;template&gt;
    &lt;GridLayout
      columns="1fr 1fr 1fr 1fr"
      rows="auto"
      gap="10px"
      verital-align="center"
      :small="{
        columns: '1fr',
        rows: 'auto auto auto auto',
      }"
    &gt;
      &lt;h1&gt;1&lt;/h1&gt;
      &lt;h1&gt;2&lt;/h1&gt;
      &lt;h1&gt;3&lt;/h1&gt;
      &lt;h1&gt;3&lt;/h1&gt;
    &lt;/GridLayout&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import { GridLayout } from '@/components/bosons'
  
  export default {
    layout: 'blank',
    components: {
      GridLayout
    },
  }
  &lt;/script&gt;
  
  
  &lt;style lang="scss" scoped&gt;
  h1 {
    background: #000;
    color: #fff;
  }
  &lt;/style&gt;
  </code></pre>
  
  <blockquote>
    <p>does not work, it generates a error <code>windows is note defined</code> in <code>if
    (this.mq() === 'small')</code></p>
  </blockquote>
  
  <p>This works perfectly in <code>pure Vue.js</code> but I understand that it does not work on Nuxt.js because it is server side rendering, it makes perfect sense, but how could I make it work?</p>
  
  <p>the closest I got was moving the style code into the <code>mounted</code> method or wrapping the style code in <code>if (process.client) {...}</code>, but any of the alternatives would generate a certain <code>delay</code>, <code>jump</code> in content, example:</p>
  
  <p><a href="https://drive.google.com/file/d/1AJ5NNe8W_BKZY5j0rhsNd8J62EA0hAdD/view" rel="nofollow noreferrer">process.client  vs without the process.client</a></p>
  
  <p><a href="https://drive.google.com/file/d/1QINCA313K53YESV8e_k4nNqylWKZaqf-/view" rel="nofollow noreferrer">jump / delay on the layout when uses process.client condition</a></p>
  
  <p>how could I make it work without delay? how could I have the screen width before the mounted, default behavior of Vue.js?</p>