Skip to content

Commit 717d088

Browse files
committed
Explain a bit better order of CSS.style_tag
1 parent 820db70 commit 717d088

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

packages/website/pages/getting-started/native.mdx

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Getting Started - OCaml
3-
showAllLanguage: true
3+
showAllLanguage: false
44
---
55

66
import { Callout } from "nextra/components";
@@ -116,7 +116,7 @@ let app =
116116
</div>;
117117
```
118118

119-
To generate the CSS on the server, you would need to use `<CSS.style_tag />`. This component will render a `<style>` with all generated stylesheet.
119+
To generate the CSS on the server, you would need to use `<CSS.style_tag />`. This component will render a `<style>` tag with all the generated styles.
120120

121121
Given a `Page` component to simulate a real-world scenario:
122122

@@ -133,10 +133,12 @@ module Page = {
133133
}
134134
```
135135

136-
If you're using dynamic CSS values, such as [dynamic-components](./dynamic-components) or [interpolation](./interpolation) based on runtime values. You would need to evaluate your app before extracting all the CSS.
136+
## A note on missing classNames
137+
138+
If you're using dynamic CSS values, such as [dynamic-components](./dynamic-components) or [interpolation](./interpolation) based on runtime values, you would need to evaluate your app before extracting all the CSS. Let me explain it with a simple example:
137139

138140
```reason
139-
module Component = {
141+
module App = {
140142
[@react.component]
141143
let make = (~value) => {
142144
let className = switch (value) {
@@ -148,12 +150,14 @@ module Component = {
148150
};
149151
```
150152

151-
This component needs to be rendered before the `CSS.style_tag` otherwise the `[%cx]` calls won't be added to the stylesheet, since they aren't being executed yet.
153+
This component (App) needs to be rendered before the `CSS.style_tag` otherwise the `[%cx]` calls won't be added to the stylesheet, since they aren't being executed yet.
154+
155+
`CSS.style_tag` returns a `<style />` with all styles injected, and you can think of CSS's stylesheet as a global registry for styles. If we place `CSS.style_tag` in the `<head>` and your `App` in the `<body>`, when we are rendering the head (happens before) the global registry won't have the dynamic classNames until App is rendered, which happens later, when React renders the `<body />`.
152156

153-
To solve this, we recommend: render the React application first, and then inject the result as `dangerouslySetInnerHTML`.
157+
To solve this, we recommend: render the React application first as a string, and then inject the result as `dangerouslySetInnerHTML` in the `<body />`. This way we ensure that the execution of the `App` happens before collecting all classNames.
154158

155159
```reason
156-
/* `App` here is the entry component of your React application, while the `Document` component is only meant to run on the server. */
160+
/* `App` here is the entry component of your React application with the interactivity from React, while the `Document` component is running on the server and is static. */
157161
module Document = {
158162
[@react.component]
159163
let make = () => {
@@ -164,24 +168,24 @@ module Document = {
164168
<CSS.style_tag />
165169
</head>
166170
<body>
167-
<div id="#root" dangerouslySetInnerHTML={"__html": app} />
171+
<div id="root" dangerouslySetInnerHTML={"__html": app} />
168172
</body>
169173
</html>
170174
}
171175
};
172176
173-
/* Let's asume we are running [dream](https://github.com/aantron/dream) */
177+
/* Let's assume we are using dream (from https://github.com/aantron/dream) */
174178
let some_server_side_handler = _request => {
175179
/* Here we render the entire HTML */
176180
Dream.html(ReactDOM.renderToString(<Document />));
177181
};
178182
```
179183

180-
### Advanced
184+
## Advanced
181185

182186
If you don't want to render the stylesheet directly, you can use `CSS.get_stylesheet` to obtain the `stylesheet` as a `string`. In this case, the hydration with the client won't be supported.
183187

184-
To make sure hydration works, you would need the following `<style/>` tag
188+
To make sure hydration works, you would need the following `<style/>` tag:
185189

186190
```ocaml
187191
React.createElement "style"
@@ -192,3 +196,12 @@ React.createElement "style"
192196
]
193197
[]
194198
```
199+
```reason
200+
React.createElement("style",
201+
[
202+
Bool("data-s", true),
203+
String("data-emotion", "css " ++ CSS.get_string_style_hashes()),
204+
DangerouslyInnerHtml(CSS.get_stylesheet())
205+
], []
206+
)
207+
```

0 commit comments

Comments
 (0)