[Gatsby]SSR 部分で window オブジェクトを参照するとビルドできない問題（鬼滅風）

# SSR 部分で window を参照しているとビルドに失敗する

Gatsby はビルド時にページを生成するのですが、ページ内に window.innerwidthとか参照しているとエラーで落ちます。


```
"window" is not available during server side rendering.

See our docs page for more info on this error: https://gatsby.dev/debug-html



  ReferenceError: window is not defined
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5565/f53ee590-ecf1-36e9-3eef-6dbfac4dadf0.png)

node でページ生成してるのだから window オブジェクトがないことは当然だ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5565/1be8b046-47dd-7f5e-c1a6-52262402fbfb.png)

window の参照なんかでビルド失敗してんじゃねーよ！！あああ💢


## 怒っても 公式みても github みても解決しないので、この超めんどくさい問題の対応方法を考えてみました。

### 一回 state にいれるようにする

```tsx
class Index extends Component {
  constructor(props) {
    super(props)
    this.state = {
      width: 0, // or your default width here
    }
  }
  componentDidMount() {
    this.handleWindowSizeChange() // Set width
    window.addEventListener('resize', this.handleWindowSizeChange)
  }

  componentWillMount() {
    // Don’t use this as the API is deprecated
  }

  // make sure to remove the listener
  // when the component is not mounted anymore
  componentWillUnmount() {
    window.removeEventListener('resize', this.handleWindowSizeChange)
  }

  handleWindowSizeChange = () => {
    this.setState({ width: window.innerWidth })
  }

  // rest of code
}
```
issue で議論されてました。
state にいれるの手間だし、おそくなるのでないなーって感じです。

### SSR のときはそのコンポーネントをマウントしない。

https://material-ui.com/api/no-ssr/

MUI に NoSSR が用意されており、こちらを使うと、
SSR のときはそのコンポーネントをマウントしないとすることができます。

MUI 以外にも似たような仕組みがあると思います。

```
import { NoSsr, List, ListItem, Tooltip } from "@material-ui/core";

略
         <NoSsr>
          <Tooltip
            id="instagram-twitter"
            title="Follow us on twitter"
            placement={window && window.innerWidth > 959 ? "top" : "left"}
            classes={{ tooltip: classes.tooltip }}
          >
            <Button
              href="https://twitter.com/CreativeTim?ref=creativetim"
              target="_blank"
              color="transparent"
              className={classes.navLink}
            >
              <i className={classes.socialIcons + " fab fa-twitter"} />
            </Button>
          </Tooltip>
         </NoSsr>
```

これは window 以外の問題も解決できるのでこれはこれでありです。

### そもそもコード書き換えない、Polyfill 的なもの

window の解決ぐらいもっと楽にできないの？！しっかりしてよ〜たんじろおお〜！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5565/26f8b9b3-2f7c-2481-6adb-0f916d7c9d6c.png)

ありました。もっとベターなアプローチが。

https://www.npmjs.com/package/ssr-window

こちらをimportすると window の参照で落ちないようようになります。
addEventListener も動作します。

```tsx
import { window } from 'ssr-window';


      <ListItem className={classes.listItem}>
        <Tooltip
          id="instagram-tooltip"
          title="Follow us on instagram"
          placement={window && window.innerWidth > 959 ? "top" : "left"}
          classes={{ tooltip: classes.tooltip }}
        >
          <Button
            color="transparent"
            href="https://www.instagram.com/CreativeTimOfficial?ref=creativetim"
            target="_blank"
            className={classes.navLink}
          >
            <i className={classes.socialIcons + " fab fa-instagram"} />
          </Button>
        </Tooltip>
```

とかかいても落ちません。

最近ぜんいつのキャラがおもしすぎて

SSRのフレームワークの中でやってくれないの？！だめだよ！もっと楽させてよ！

とか思っちゃいました。