https://github.com/patte/next13-styletron-baseui-colorscheme
Next.js v13 app dir (beta), React v18 project with Styletron, BaseWeb and detection of the prefered color-scheme (dark, light).
https://github.com/patte/next13-styletron-baseui-colorscheme
Last synced: about 1 month ago
JSON representation
Next.js v13 app dir (beta), React v18 project with Styletron, BaseWeb and detection of the prefered color-scheme (dark, light).
- Host: GitHub
- URL: https://github.com/patte/next13-styletron-baseui-colorscheme
- Owner: patte
- Created: 2023-01-17T00:29:47.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-01-31T17:03:02.000Z (over 2 years ago)
- Last Synced: 2025-04-04T11:51:28.359Z (about 2 months ago)
- Language: TypeScript
- Homepage: https://next13-styletron-baseui-colorscheme.fly.dev/
- Size: 98.6 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## next13-styletron-baseui-colorScheme-example
A [Next.js](https://nextjs.org/) v13-beta, [React](https://reactjs.org) v18 project with [Styletron](https://www.styletron.org/), [BaseWeb](https://baseweb.design/) and detection / selection of the prefered color-scheme (dark, light).
[Demo](https://next13-styletron-baseui-colorscheme.fly.dev/)
- ✅ Next.js v13 beta server components
- ✅ Styletron SSR with `useServerInsertedHTML`
- ✅ BaseWeb with custom theme
- ✅ render styletron/baseWeb components in client components
- ❌ render styletron/baseWeb components in server components (only use it in client components)
- ✅ detect prefered color scheme
- ✅ toggle color scheme
- ✅ SSR the correct color scheme without flash on first visit in chromium `>= 93`
- ✅ SSR the correct color scheme after on consecutive visits in all browsers
- ✅ change to the correct preferred color scheme on mount in all browsers
- ❌ SSR the correct color scheme dark without flash on first visit in chromium `< 93` or other browsers.### Features
#### Next.js v13 beta
With the `app` directory for react server components and data fetching.
#### Styletron
The [SsrStyletronProvider](lib/ui/StyletronProvider.tsx) is use to get the stylesheets after prerendering and setting if as a style tag with the class `_styletron_hydrate_` in the head of the SSR response. On the client the provider rehydrates styletron by finding the element in the head.
Rendering styletron components in client components works fine. In server components it doesn't because styletron uses `createContext`. Issue: https://github.com/styletron/styletron/issues/430
#### color-scheme
The prefered color scheme of the browser can be detected by the `prefers-color-scheme: light | dark` media query. For style systems which use css variables,
server side rendering (SSR) is easy: render and send the browser all css variables (for light and dark) and let it choose which to use. Style systems which need to use the color scheme in javascript, SSR becomes more difficult. As the server needs to decide which color scheme to render.The [colorScheme lib](lib/ui/colorScheme) solves this with the following steps:
- The [middleware](lib/ui/colorScheme/middleware.ts) asks the browser to provide the `Sec-CH-Prefers-ColorScheme` header (supported by Chromium `>= 93`)
- The [SsrColorSchemeProvider](lib/ui/colorScheme/server.tsx) (server component) reads the header and sets it as a prop on the [ClientProvider](lib/ui/colorScheme/client.tsx) (client component).
- The [SsrColorSchemeProvider](lib/ui/colorScheme/server.tsx) (server component) also reads the `prefers-color-scheme` cookie from the request and sets it as a prop on the ClientProvider.
- The [ClientProvider](lib/ui/colorScheme/client.tsx)
- uses the these two props to derive the color scheme: cookie wins over header. If no preference can be determined `light` is assumed as the default. It then provides a context value for consumption downstream (by the baseweb provider and the [toggle button](ui/Navigation.tsx#L13)).
- provides a toogle function that sets the user's prefered color scheme in the cookie and updates the context value.
- upon first mount checks if the current color scheme (set by SSR) is different from the medie query `prefers-color-scheme` and if no cookie is set (no local preference), "corrects" the wrong guess by toggling the color scheme to the correct one. This saves the preference in the cookie, so the next SSR will be correct.
- during it's livetime: listens for media query changes to `prefers-color-scheme` and toggles the color scheme accordingly.This works in all browsers, but the first visit in chromium `>= 93` will flash the wrong color scheme before the javascript kicks in and toggles it to the correct one.
#### BaseWeb
The [SsrBaseProvider](lib/ui/BaseProvider.tsx) is used to create the baseweb theme based on the active color scheme.
Issue for react 18: https://github.com/uber/baseweb/issues/4900
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
```Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.