0
# Provider and Context System
1
2
React JSS provides a comprehensive provider and context system for JSS configuration management and sharing JSS instances, registries, and settings across your application component tree. This system is essential for server-side rendering, style isolation, and advanced JSS configuration.
3
4
## Capabilities
5
6
### JssProvider Component
7
8
Context provider for JSS configuration and registry management, enabling fine-grained control over JSS behavior across your application.
9
10
```typescript { .api }
11
/**
12
* JSS configuration provider component
13
* Provides JSS instance, registry, and configuration to child components
14
*/
15
const JssProvider: ComponentType<{
16
/** Custom JSS instance to use */
17
jss?: Jss;
18
/** Sheets registry for style collection (essential for SSR) */
19
registry?: SheetsRegistry;
20
/** Custom class name generation function */
21
generateId?: GenerateId;
22
/** Prefix for all generated class names */
23
classNamePrefix?: string;
24
/** Disable style generation (useful for SSR hydration) */
25
disableStylesGeneration?: boolean;
26
/** Child components */
27
children: ReactNode;
28
/** Options for ID generation */
29
id?: CreateGenerateIdOptions;
30
/** Whether running in server-side rendering mode */
31
isSSR?: boolean;
32
}>;
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import React from 'react';
39
import { JssProvider, SheetsRegistry, createGenerateId } from 'react-jss';
40
41
// Basic usage
42
function App() {
43
return (
44
<JssProvider>
45
<MyComponents />
46
</JssProvider>
47
);
48
}
49
50
// Advanced configuration
51
function AdvancedApp() {
52
const registry = new SheetsRegistry();
53
const generateId = createGenerateId();
54
55
return (
56
<JssProvider
57
registry={registry}
58
generateId={generateId}
59
classNamePrefix="app-"
60
>
61
<MyComponents />
62
</JssProvider>
63
);
64
}
65
```
66
67
### Server-Side Rendering Setup
68
69
Configure JSS for server-side rendering with style extraction:
70
71
```typescript
72
import React from 'react';
73
import { renderToString } from 'react-dom/server';
74
import { JssProvider, SheetsRegistry, createGenerateId } from 'react-jss';
75
76
// Server-side rendering function
77
function renderServerSide(App) {
78
// Create fresh registry and ID generator for each request
79
const registry = new SheetsRegistry();
80
const generateId = createGenerateId();
81
82
const html = renderToString(
83
<JssProvider registry={registry} generateId={generateId} isSSR>
84
<App />
85
</JssProvider>
86
);
87
88
// Extract CSS for injection into HTML
89
const css = registry.toString();
90
91
return { html, css };
92
}
93
94
// Usage in server
95
app.get('/', (req, res) => {
96
const { html, css } = renderServerSide(MyApp);
97
98
res.send(`
99
<!DOCTYPE html>
100
<html>
101
<head>
102
<style id="server-side-jss">${css}</style>
103
</head>
104
<body>
105
<div id="root">${html}</div>
106
</body>
107
</html>
108
`);
109
});
110
```
111
112
### Client-Side Hydration
113
114
Properly configure client-side hydration to avoid style conflicts:
115
116
```typescript
117
import React from 'react';
118
import { hydrate } from 'react-dom';
119
import { JssProvider } from 'react-jss';
120
121
function ClientApp() {
122
// Remove server-side styles after hydration
123
React.useEffect(() => {
124
const jssStyles = document.querySelector('#server-side-jss');
125
if (jssStyles && jssStyles.parentElement) {
126
jssStyles.parentElement.removeChild(jssStyles);
127
}
128
}, []);
129
130
return (
131
<JssProvider disableStylesGeneration={false}>
132
<App />
133
</JssProvider>
134
);
135
}
136
137
// Hydrate on client
138
hydrate(<ClientApp />, document.getElementById('root'));
139
```
140
141
### Custom JSS Instance
142
143
Use a custom JSS instance with specific plugins and configuration:
144
145
```typescript
146
import React from 'react';
147
import { create } from 'jss';
148
import preset from 'jss-preset-default';
149
import rtl from 'jss-rtl';
150
import { JssProvider } from 'react-jss';
151
152
// Create custom JSS instance
153
const customJss = create({
154
...preset(),
155
// Add RTL support
156
plugins: [...preset().plugins, rtl()]
157
});
158
159
function App() {
160
return (
161
<JssProvider jss={customJss}>
162
<MyComponents />
163
</JssProvider>
164
);
165
}
166
```
167
168
### Multiple JssProvider Nesting
169
170
Nest multiple JssProviders for different configurations in different parts of your app:
171
172
```typescript
173
import React from 'react';
174
import { JssProvider, SheetsRegistry } from 'react-jss';
175
176
function App() {
177
const mainRegistry = new SheetsRegistry();
178
const adminRegistry = new SheetsRegistry();
179
180
return (
181
<JssProvider registry={mainRegistry} classNamePrefix="main-">
182
<MainApp />
183
184
<JssProvider registry={adminRegistry} classNamePrefix="admin-">
185
<AdminPanel />
186
</JssProvider>
187
</JssProvider>
188
);
189
}
190
```
191
192
### JssContext Direct Access
193
194
Access JSS context directly for advanced use cases:
195
196
```typescript { .api }
197
/**
198
* React context for JSS configuration
199
* Provides direct access to JSS instance and configuration
200
*/
201
const JssContext: Context<JssContextValue>;
202
203
interface JssContextValue {
204
/** JSS instance */
205
jss?: Jss;
206
/** Sheets registry */
207
registry?: SheetsRegistry;
208
/** Internal stylesheet managers */
209
managers?: Managers;
210
/** Sheet creation options */
211
sheetOptions: StyleSheetFactoryOptions;
212
/** Whether style generation is disabled */
213
disableStylesGeneration: boolean;
214
/** Whether in SSR mode */
215
isSSR: boolean;
216
}
217
218
interface Managers {
219
[key: number]: StyleSheet;
220
}
221
```
222
223
**Usage Examples:**
224
225
```typescript
226
import React, { useContext } from 'react';
227
import { JssContext } from 'react-jss';
228
229
function DebugComponent() {
230
const context = useContext(JssContext);
231
232
return (
233
<div>
234
<h3>JSS Context Debug Info</h3>
235
<p>JSS Instance: {context.jss ? 'Available' : 'Not Available'}</p>
236
<p>Registry: {context.registry ? 'Available' : 'Not Available'}</p>
237
<p>SSR Mode: {context.isSSR ? 'Yes' : 'No'}</p>
238
<p>Styles Generation: {context.disableStylesGeneration ? 'Disabled' : 'Enabled'}</p>
239
<p>Active Sheets: {context.managers ? Object.keys(context.managers).length : 0}</p>
240
</div>
241
);
242
}
243
```
244
245
### Custom ID Generation
246
247
Configure custom class name generation for consistent naming:
248
249
```typescript
250
import React from 'react';
251
import { JssProvider, createGenerateId } from 'react-jss';
252
253
// Create custom ID generator
254
const generateId = createGenerateId({
255
minify: process.env.NODE_ENV === 'production'
256
});
257
258
// Or create completely custom generator
259
const customGenerateId = (rule, sheet) => {
260
const prefix = sheet?.options?.classNamePrefix || '';
261
const name = rule.key;
262
const id = Math.random().toString(36).substr(2, 9);
263
return `${prefix}${name}-${id}`;
264
};
265
266
function App() {
267
return (
268
<JssProvider generateId={customGenerateId}>
269
<MyComponents />
270
</JssProvider>
271
);
272
}
273
```
274
275
### Style Isolation with Class Name Prefixes
276
277
Use class name prefixes to isolate styles between different parts of your application:
278
279
```typescript
280
import React from 'react';
281
import { JssProvider, createUseStyles } from 'react-jss';
282
283
const useStyles = createUseStyles({
284
button: {
285
padding: '10px',
286
backgroundColor: 'blue',
287
color: 'white'
288
}
289
});
290
291
function ComponentA() {
292
const classes = useStyles();
293
return <button className={classes.button}>Component A Button</button>;
294
}
295
296
function ComponentB() {
297
const classes = useStyles();
298
return <button className={classes.button}>Component B Button</button>;
299
}
300
301
function App() {
302
return (
303
<div>
304
{/* Component A styles will have "feature-a-" prefix */}
305
<JssProvider classNamePrefix="feature-a-">
306
<ComponentA />
307
</JssProvider>
308
309
{/* Component B styles will have "feature-b-" prefix */}
310
<JssProvider classNamePrefix="feature-b-">
311
<ComponentB />
312
</JssProvider>
313
</div>
314
);
315
}
316
// Results in different CSS class names:
317
// .feature-a-button-0-1-2 and .feature-b-button-0-1-3
318
```
319
320
### Performance Optimization
321
322
Optimize performance by reusing JSS instances and registries:
323
324
```typescript
325
import React, { useMemo } from 'react';
326
import { JssProvider, SheetsRegistry, createGenerateId } from 'react-jss';
327
328
function OptimizedApp() {
329
// Memoize JSS configuration to prevent recreation
330
const jssConfig = useMemo(() => ({
331
registry: new SheetsRegistry(),
332
generateId: createGenerateId()
333
}), []);
334
335
return (
336
<JssProvider
337
registry={jssConfig.registry}
338
generateId={jssConfig.generateId}
339
classNamePrefix="app-"
340
>
341
<App />
342
</JssProvider>
343
);
344
}
345
```
346
347
### Development vs Production Configuration
348
349
Configure different settings for development and production:
350
351
```typescript
352
import React from 'react';
353
import { JssProvider, createGenerateId } from 'react-jss';
354
355
function App() {
356
const isDevelopment = process.env.NODE_ENV === 'development';
357
358
const generateId = createGenerateId({
359
minify: !isDevelopment,
360
// Use readable class names in development
361
seed: isDevelopment ? '' : undefined
362
});
363
364
return (
365
<JssProvider
366
generateId={generateId}
367
classNamePrefix={isDevelopment ? 'dev-' : ''}
368
>
369
<MyApp />
370
</JssProvider>
371
);
372
}
373
```
374
375
## Types
376
377
```typescript { .api }
378
interface StyleSheetFactoryOptions {
379
media?: string;
380
meta?: string;
381
index?: number;
382
link?: boolean;
383
element?: HTMLStyleElement;
384
insertionPoint?: string | HTMLElement;
385
classNamePrefix?: string;
386
}
387
388
interface CreateGenerateIdOptions {
389
minify?: boolean;
390
seed?: string;
391
}
392
393
type GenerateId = (rule: Rule, sheet?: StyleSheet) => string;
394
395
interface SheetsRegistry {
396
add(sheet: StyleSheet): void;
397
remove(sheet: StyleSheet): void;
398
toString(options?: {format?: boolean; allowEmpty?: boolean}): string;
399
registry: StyleSheet[];
400
}
401
```