0
# Style Registry
1
2
Server-side rendering and style management system for handling style injection, deduplication, and extraction in React applications.
3
4
## Capabilities
5
6
### StyleRegistry Component
7
8
Provider component that manages the style registry context for a React component tree.
9
10
```typescript { .api }
11
/**
12
* Provider component for style registry context
13
* @param children - React children to provide registry context to
14
* @param registry - Optional registry instance, creates new one if not provided
15
*/
16
function StyleRegistry({
17
children,
18
registry
19
}: {
20
children: JSX.Element | import('react').ReactNode;
21
registry?: StyledJsxStyleRegistry;
22
}): JSX.Element;
23
```
24
25
**Usage Examples:**
26
27
```jsx
28
import React from 'react';
29
import { StyleRegistry } from 'styled-jsx';
30
import App from './App';
31
32
// Basic usage - automatic registry creation
33
function Root() {
34
return (
35
<StyleRegistry>
36
<App />
37
</StyleRegistry>
38
);
39
}
40
41
// Custom registry instance
42
import { createStyleRegistry } from 'styled-jsx';
43
44
function ServerApp() {
45
const registry = createStyleRegistry();
46
47
return (
48
<StyleRegistry registry={registry}>
49
<App />
50
</StyleRegistry>
51
);
52
}
53
```
54
55
### createStyleRegistry Function
56
57
Factory function that creates a new style registry instance for manual style management.
58
59
```typescript { .api }
60
/**
61
* Creates a new style registry instance
62
* @returns New StyledJsxStyleRegistry instance
63
*/
64
function createStyleRegistry(): StyledJsxStyleRegistry;
65
```
66
67
**Usage Examples:**
68
69
```jsx
70
import { createStyleRegistry } from 'styled-jsx';
71
72
// Server-side rendering setup
73
function renderApp() {
74
const registry = createStyleRegistry();
75
76
// Render app with registry
77
const appHtml = ReactDOM.renderToString(
78
<StyleRegistry registry={registry}>
79
<App />
80
</StyleRegistry>
81
);
82
83
// Extract styles for SSR
84
const styles = registry.styles();
85
86
return { appHtml, styles };
87
}
88
89
// Multiple registry instances for isolation
90
function createIsolatedApp() {
91
const registry1 = createStyleRegistry();
92
const registry2 = createStyleRegistry();
93
94
return (
95
<>
96
<StyleRegistry registry={registry1}>
97
<ComponentA />
98
</StyleRegistry>
99
<StyleRegistry registry={registry2}>
100
<ComponentB />
101
</StyleRegistry>
102
</>
103
);
104
}
105
```
106
107
### useStyleRegistry Hook
108
109
React hook that provides access to the current style registry from context.
110
111
```typescript { .api }
112
/**
113
* Hook to access current style registry from context
114
* @returns Current StyledJsxStyleRegistry instance or null if none provided
115
*/
116
function useStyleRegistry(): StyledJsxStyleRegistry;
117
```
118
119
**Usage Examples:**
120
121
```jsx
122
import React from 'react';
123
import { useStyleRegistry } from 'styled-jsx';
124
125
// Custom component that needs direct registry access
126
function StyleDebugger() {
127
const registry = useStyleRegistry();
128
129
if (!registry) {
130
return <div>No style registry available</div>;
131
}
132
133
return (
134
<div>
135
<h3>Current Styles:</h3>
136
<div>{registry.styles()}</div>
137
<button onClick={() => registry.flush()}>
138
Clear All Styles
139
</button>
140
</div>
141
);
142
}
143
144
// Component that manually manages styles
145
function ManualStyleComponent() {
146
const registry = useStyleRegistry();
147
148
React.useEffect(() => {
149
if (registry) {
150
// Add custom style programmatically
151
registry.add({
152
id: 'manual-style',
153
children: '.manual { color: red; }'
154
});
155
156
return () => {
157
// Clean up on unmount
158
registry.remove({
159
id: 'manual-style',
160
children: '.manual { color: red; }'
161
});
162
};
163
}
164
}, [registry]);
165
166
return <div className="manual">Manually styled content</div>;
167
}
168
```
169
170
### StyledJsxStyleRegistry Interface
171
172
The registry interface that manages style lifecycle, injection, and extraction.
173
174
```typescript { .api }
175
interface StyledJsxStyleRegistry {
176
/**
177
* Get array of style elements for rendering
178
* @param options - Optional configuration for style rendering
179
* @param options.nonce - CSP nonce for style tags
180
* @returns Array of React style elements
181
*/
182
styles(options?: { nonce?: string }): JSX.Element[];
183
184
/**
185
* Clear all styles from registry
186
* Removes all tracked styles and resets internal state
187
*/
188
flush(): void;
189
190
/**
191
* Add style to registry
192
* @param props - Style properties including id and CSS content
193
*/
194
add(props: any): void;
195
196
/**
197
* Remove style from registry
198
* @param props - Style properties to identify style for removal
199
*/
200
remove(props: any): void;
201
}
202
```
203
204
**Usage Examples:**
205
206
```jsx
207
// Server-side rendering with styles extraction
208
import React from 'react';
209
import ReactDOM from 'react-dom/server';
210
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
211
212
function ServerRenderer({ App }) {
213
const registry = createStyleRegistry();
214
215
// Render app to string
216
const appHtml = ReactDOM.renderToString(
217
<StyleRegistry registry={registry}>
218
<App />
219
</StyleRegistry>
220
);
221
222
// Extract all styles
223
const styles = registry.styles({ nonce: 'xyz123' });
224
225
// Create full HTML document
226
const document = ReactDOM.renderToStaticMarkup(
227
<html>
228
<head>
229
<title>My App</title>
230
{styles}
231
</head>
232
<body>
233
<div id="root" dangerouslySetInnerHTML={{ __html: appHtml }} />
234
</body>
235
</html>
236
);
237
238
return '<!DOCTYPE html>' + document;
239
}
240
241
// Manual style management
242
function StyleManager() {
243
const registry = createStyleRegistry();
244
245
const addGlobalStyles = () => {
246
registry.add({
247
id: 'global-reset',
248
children: `
249
* { margin: 0; padding: 0; box-sizing: border-box; }
250
body { font-family: Arial, sans-serif; }
251
`
252
});
253
};
254
255
const removeGlobalStyles = () => {
256
registry.remove({
257
id: 'global-reset',
258
children: `
259
* { margin: 0; padding: 0; box-sizing: border-box; }
260
body { font-family: Arial, sans-serif; }
261
`
262
});
263
};
264
265
const clearAllStyles = () => {
266
registry.flush();
267
};
268
269
return (
270
<StyleRegistry registry={registry}>
271
<div>
272
<button onClick={addGlobalStyles}>Add Global Styles</button>
273
<button onClick={removeGlobalStyles}>Remove Global Styles</button>
274
<button onClick={clearAllStyles}>Clear All Styles</button>
275
<div>Current styles: {registry.styles().length}</div>
276
</div>
277
</StyleRegistry>
278
);
279
}
280
```
281
282
### Server-Side Rendering Pattern
283
284
Complete SSR setup pattern for Next.js and custom React applications.
285
286
```jsx { .api }
287
// Server-side rendering with style extraction
288
const registry = createStyleRegistry();
289
const appHtml = ReactDOM.renderToString(
290
<StyleRegistry registry={registry}>
291
<App />
292
</StyleRegistry>
293
);
294
const styles = registry.styles();
295
```
296
297
**Complete SSR Example:**
298
299
```jsx
300
// pages/_document.js (Next.js)
301
import Document, { Html, Head, Main, NextScript } from 'next/document';
302
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
303
304
export default class MyDocument extends Document {
305
static async getInitialProps(ctx) {
306
const registry = createStyleRegistry();
307
const originalRenderPage = ctx.renderPage;
308
309
ctx.renderPage = () =>
310
originalRenderPage({
311
enhanceApp: (App) => (props) => (
312
<StyleRegistry registry={registry}>
313
<App {...props} />
314
</StyleRegistry>
315
),
316
});
317
318
const initialProps = await Document.getInitialProps(ctx);
319
const styles = registry.styles();
320
321
return {
322
...initialProps,
323
styles: (
324
<>
325
{initialProps.styles}
326
{styles}
327
</>
328
),
329
};
330
}
331
332
render() {
333
return (
334
<Html>
335
<Head />
336
<body>
337
<Main />
338
<NextScript />
339
</body>
340
</Html>
341
);
342
}
343
}
344
345
// Custom Express.js server
346
import express from 'express';
347
import React from 'react';
348
import ReactDOM from 'react-dom/server';
349
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
350
import App from './App';
351
352
const server = express();
353
354
server.get('*', (req, res) => {
355
const registry = createStyleRegistry();
356
357
const appHtml = ReactDOM.renderToString(
358
<StyleRegistry registry={registry}>
359
<App url={req.url} />
360
</StyleRegistry>
361
);
362
363
const styles = registry.styles();
364
365
const html = `
366
<!DOCTYPE html>
367
<html>
368
<head>
369
<title>My App</title>
370
<meta charset="utf-8">
371
<meta name="viewport" content="width=device-width, initial-scale=1">
372
${ReactDOM.renderToStaticMarkup(<>{styles}</>)}
373
</head>
374
<body>
375
<div id="root">${appHtml}</div>
376
<script src="/bundle.js"></script>
377
</body>
378
</html>
379
`;
380
381
res.send(html);
382
});
383
384
server.listen(3000);
385
```
386
387
### JSXStyle Component
388
389
Internal style component used by the Babel plugin to inject styles. Also provides utilities for dynamic style handling.
390
391
```typescript { .api }
392
/**
393
* Internal JSX style component (auto-imported by Babel plugin)
394
* @param props - Style properties including id, dynamic values, and CSS content
395
* @returns null (styles are injected into DOM)
396
*/
397
function JSXStyle(props: any): null;
398
399
namespace JSXStyle {
400
/**
401
* Static method for computing dynamic style class names
402
* @param info - Array of tuples containing base IDs and dynamic properties
403
* @returns Space-separated string of computed style IDs
404
*/
405
function dynamic(info: Array<[string, any]>): string;
406
}
407
```
408
409
**Usage Examples:**
410
411
```jsx
412
import JSXStyle from 'styled-jsx/style';
413
414
// Manual usage (typically not needed - Babel handles this)
415
function ManualStyledComponent() {
416
return (
417
<div className="jsx-123">
418
<JSXStyle
419
id="123"
420
children={`
421
.jsx-123 {
422
color: red;
423
font-size: 16px;
424
}
425
`}
426
/>
427
Content
428
</div>
429
);
430
}
431
432
// Dynamic style ID computation
433
function DynamicStyleExample() {
434
const dynamicInfo = [
435
['base-id-1', { color: 'red', size: 'large' }],
436
['base-id-2', { theme: 'dark' }]
437
];
438
439
const computedClasses = JSXStyle.dynamic(dynamicInfo);
440
// Returns: "jsx-computed-id-1 jsx-computed-id-2"
441
442
return (
443
<div className={computedClasses}>
444
Dynamically styled content
445
</div>
446
);
447
}
448
```