Server Side Rendering
Unistyles can render styles on the server-side, which is useful, for example, for SEO purposes.
Initial configuration
Configure your unistyles.ts
file as it’s listed in the Getting started section.
Server side configuration
You just need to modify the __document.ts
or __document.js
file in your project’s root by importing
unistyles.ts
file.
import '../unistyles'
export const getInitialProps = async ({ renderPage }) => { AppRegistry.registerComponent('Main', () => Main)
const { getStyleElement } = AppRegistry.getApplication('Main') const page = await renderPage() const styles = [ <style key="style-reset" dangerouslySetInnerHTML={{ __html: style }} />, getStyleElement() ]
return { ...page, styles: React.Children.toArray(styles) }}
Client side configuration
To setup the listeners and Unistyles bindings, simply repeat the process,
but this time with _app.tsx
file.
import '../unistyles'
export const MyApp = ({ Component, pageProps }: SolitoAppProps) => { // your component}
Some dynamic features like breakpoint are not available on the server. That’s why you need additional configuration with the isClient
flag.
import React, { useEffect, useState } from 'react'import { View, Text, ActivityIndicator } from 'react-native'import { useStyles } from 'react-native-unistyles'
export const HomeScreen = () => { const { styles, breakpoint, theme } = useStyles(stylesheet) const [isClient, setIsClient] = useState(false)
useEffect(() => { // this will run only on client side setIsClient(true) }, [])
return ( <View style={styles.container}> <Text style={styles.text}> Welcome to Expo + Next.js + Unistyles 👋 </Text> <Text> Current breakpoint: {isClient ? breakpoint : null} </Text> <Text> I like {theme.colors.barbie} color </Text> <View style={styles.linksContainer}> <TextLink href="/user/"> Click me 🦄 </TextLink> </View> {!isClient && ( <View style={styles.loader}> <ActivityIndicator /> </View> )} </View> )}
const stylesheet = ...
Adaptive themes with SSR
If you want to support adaptiveThemes in SRR you can’t set it on server, because the server is unaware of your client’s preferences.
Instead, manually select either light
or dark
theme on the server:
UnistylesRegistry .addBreakpoints(breakpoints) .addThemes({ light: lightTheme, dark: darkTheme }) .addConfig({ adaptiveThemes: true, // can't be used with SSR initialTheme: 'light', // or dark experimentalCSSMediaQueries: true })
Then, on the client side, you can use the UnistylesRuntime
to enable adaptiveThemes
after the first render:
useEffect(() => { // this will run only on client side setIsClient(true) UnistylesRuntime.setAdaptiveThemes(true)}, [])
The client will not notice the difference, and you will avoid hydration errors.