Skip to content

Commit 36b7b20

Browse files
authored
fix: Hydration warnings / mismatched styles due to SSR (#31)
While starting on the create workspace flow - I noticed some weird CSS issues. In particular, intermittently, the web UI would render like this: ![image](https://user-images.githubusercontent.com/88213859/150072041-f1c6b9b2-941c-41a8-ad84-b7b163b3504f.png) ...and when that happened, there'd be an accompanying error in the console: ![image](https://user-images.githubusercontent.com/88213859/150072101-d98cb714-d133-4532-8a02-a7642d242a02.png) The issue is that NextJS is trying to render the page on the server and use the styles - and sometimes the classnames mismatch between server-side and client-side rendering. We actually worked around this in `cdr/m` with a `<SafeHydration />` component and a custom `_document.tsx` This change ports over both the component and custom `_document.tsx`. I noticed, in addition, I missed the favicons when switching to NextJS, so I brought those over too.
1 parent 6e6eee6 commit 36b7b20

File tree

5 files changed

+49
-4
lines changed

5 files changed

+49
-4
lines changed

site/pages/_app.tsx

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,27 @@ const Contents: React.FC<AppProps> = ({ Component, pageProps }) => {
4040
)
4141
}
4242

43+
/**
44+
* ClientRender is a component that only allows its children to be rendered
45+
* client-side. This check is performed by querying the existence of the window
46+
* global.
47+
*/
48+
const ClientRender: React.FC = ({ children }) => (
49+
<div suppressHydrationWarning>{typeof window === "undefined" ? null : children}</div>
50+
)
51+
4352
/**
4453
* <App /> is the root rendering logic of the application - setting up our router
4554
* and any contexts / global state management.
4655
*/
4756
const MyApp: React.FC<AppProps> = (appProps) => {
4857
return (
49-
<ThemeProvider theme={dark}>
50-
<CssBaseline />
51-
<Contents {...appProps} />
52-
</ThemeProvider>
58+
<ClientRender>
59+
<ThemeProvider theme={dark}>
60+
<CssBaseline />
61+
<Contents {...appProps} />
62+
</ThemeProvider>
63+
</ClientRender>
5364
)
5465
}
5566

site/pages/_document.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Document, { DocumentContext, Head, Html, Main, NextScript } from "next/document"
2+
import React from "react"
3+
4+
class MyDocument extends Document {
5+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
6+
static async getInitialProps(ctx: DocumentContext) {
7+
const initialProps = await Document.getInitialProps(ctx)
8+
return { ...initialProps }
9+
}
10+
11+
render(): JSX.Element {
12+
return (
13+
<Html>
14+
<Head>
15+
<meta charSet="utf-8" />
16+
<meta name="theme-color" content="#17172E" />
17+
<meta name="application-name" content="Coder" />
18+
<meta property="og:type" content="website" />
19+
<meta property="csp-nonce" content="{{ .CSP.Nonce }}" />
20+
<link crossOrigin="use-credentials" rel="mask-icon" href="/static/favicon.svg" color="#000000" />
21+
<link rel="alternate icon" type="image/png" href="/static/favicon.png" />
22+
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg" />
23+
</Head>
24+
<body>
25+
<Main />
26+
<NextScript />
27+
</body>
28+
</Html>
29+
)
30+
}
31+
}
32+
33+
export default MyDocument

site/static/favicon.ico

4.19 KB
Binary file not shown.

site/static/favicon.png

571 Bytes
Loading

site/static/favicon.svg

Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)