JSS integration with React providing CSS-in-JS styling solutions with theming support
—
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.
Context provider for JSS configuration and registry management, enabling fine-grained control over JSS behavior across your application.
/**
* JSS configuration provider component
* Provides JSS instance, registry, and configuration to child components
*/
const JssProvider: ComponentType<{
/** Custom JSS instance to use */
jss?: Jss;
/** Sheets registry for style collection (essential for SSR) */
registry?: SheetsRegistry;
/** Custom class name generation function */
generateId?: GenerateId;
/** Prefix for all generated class names */
classNamePrefix?: string;
/** Disable style generation (useful for SSR hydration) */
disableStylesGeneration?: boolean;
/** Child components */
children: ReactNode;
/** Options for ID generation */
id?: CreateGenerateIdOptions;
/** Whether running in server-side rendering mode */
isSSR?: boolean;
}>;Usage Examples:
import React from 'react';
import { JssProvider, SheetsRegistry, createGenerateId } from 'react-jss';
// Basic usage
function App() {
return (
<JssProvider>
<MyComponents />
</JssProvider>
);
}
// Advanced configuration
function AdvancedApp() {
const registry = new SheetsRegistry();
const generateId = createGenerateId();
return (
<JssProvider
registry={registry}
generateId={generateId}
classNamePrefix="app-"
>
<MyComponents />
</JssProvider>
);
}Configure JSS for server-side rendering with style extraction:
import React from 'react';
import { renderToString } from 'react-dom/server';
import { JssProvider, SheetsRegistry, createGenerateId } from 'react-jss';
// Server-side rendering function
function renderServerSide(App) {
// Create fresh registry and ID generator for each request
const registry = new SheetsRegistry();
const generateId = createGenerateId();
const html = renderToString(
<JssProvider registry={registry} generateId={generateId} isSSR>
<App />
</JssProvider>
);
// Extract CSS for injection into HTML
const css = registry.toString();
return { html, css };
}
// Usage in server
app.get('/', (req, res) => {
const { html, css } = renderServerSide(MyApp);
res.send(`
<!DOCTYPE html>
<html>
<head>
<style id="server-side-jss">${css}</style>
</head>
<body>
<div id="root">${html}</div>
</body>
</html>
`);
});Properly configure client-side hydration to avoid style conflicts:
import React from 'react';
import { hydrate } from 'react-dom';
import { JssProvider } from 'react-jss';
function ClientApp() {
// Remove server-side styles after hydration
React.useEffect(() => {
const jssStyles = document.querySelector('#server-side-jss');
if (jssStyles && jssStyles.parentElement) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<JssProvider disableStylesGeneration={false}>
<App />
</JssProvider>
);
}
// Hydrate on client
hydrate(<ClientApp />, document.getElementById('root'));Use a custom JSS instance with specific plugins and configuration:
import React from 'react';
import { create } from 'jss';
import preset from 'jss-preset-default';
import rtl from 'jss-rtl';
import { JssProvider } from 'react-jss';
// Create custom JSS instance
const customJss = create({
...preset(),
// Add RTL support
plugins: [...preset().plugins, rtl()]
});
function App() {
return (
<JssProvider jss={customJss}>
<MyComponents />
</JssProvider>
);
}Nest multiple JssProviders for different configurations in different parts of your app:
import React from 'react';
import { JssProvider, SheetsRegistry } from 'react-jss';
function App() {
const mainRegistry = new SheetsRegistry();
const adminRegistry = new SheetsRegistry();
return (
<JssProvider registry={mainRegistry} classNamePrefix="main-">
<MainApp />
<JssProvider registry={adminRegistry} classNamePrefix="admin-">
<AdminPanel />
</JssProvider>
</JssProvider>
);
}Access JSS context directly for advanced use cases:
/**
* React context for JSS configuration
* Provides direct access to JSS instance and configuration
*/
const JssContext: Context<JssContextValue>;
interface JssContextValue {
/** JSS instance */
jss?: Jss;
/** Sheets registry */
registry?: SheetsRegistry;
/** Internal stylesheet managers */
managers?: Managers;
/** Sheet creation options */
sheetOptions: StyleSheetFactoryOptions;
/** Whether style generation is disabled */
disableStylesGeneration: boolean;
/** Whether in SSR mode */
isSSR: boolean;
}
interface Managers {
[key: number]: StyleSheet;
}Usage Examples:
import React, { useContext } from 'react';
import { JssContext } from 'react-jss';
function DebugComponent() {
const context = useContext(JssContext);
return (
<div>
<h3>JSS Context Debug Info</h3>
<p>JSS Instance: {context.jss ? 'Available' : 'Not Available'}</p>
<p>Registry: {context.registry ? 'Available' : 'Not Available'}</p>
<p>SSR Mode: {context.isSSR ? 'Yes' : 'No'}</p>
<p>Styles Generation: {context.disableStylesGeneration ? 'Disabled' : 'Enabled'}</p>
<p>Active Sheets: {context.managers ? Object.keys(context.managers).length : 0}</p>
</div>
);
}Configure custom class name generation for consistent naming:
import React from 'react';
import { JssProvider, createGenerateId } from 'react-jss';
// Create custom ID generator
const generateId = createGenerateId({
minify: process.env.NODE_ENV === 'production'
});
// Or create completely custom generator
const customGenerateId = (rule, sheet) => {
const prefix = sheet?.options?.classNamePrefix || '';
const name = rule.key;
const id = Math.random().toString(36).substr(2, 9);
return `${prefix}${name}-${id}`;
};
function App() {
return (
<JssProvider generateId={customGenerateId}>
<MyComponents />
</JssProvider>
);
}Use class name prefixes to isolate styles between different parts of your application:
import React from 'react';
import { JssProvider, createUseStyles } from 'react-jss';
const useStyles = createUseStyles({
button: {
padding: '10px',
backgroundColor: 'blue',
color: 'white'
}
});
function ComponentA() {
const classes = useStyles();
return <button className={classes.button}>Component A Button</button>;
}
function ComponentB() {
const classes = useStyles();
return <button className={classes.button}>Component B Button</button>;
}
function App() {
return (
<div>
{/* Component A styles will have "feature-a-" prefix */}
<JssProvider classNamePrefix="feature-a-">
<ComponentA />
</JssProvider>
{/* Component B styles will have "feature-b-" prefix */}
<JssProvider classNamePrefix="feature-b-">
<ComponentB />
</JssProvider>
</div>
);
}
// Results in different CSS class names:
// .feature-a-button-0-1-2 and .feature-b-button-0-1-3Optimize performance by reusing JSS instances and registries:
import React, { useMemo } from 'react';
import { JssProvider, SheetsRegistry, createGenerateId } from 'react-jss';
function OptimizedApp() {
// Memoize JSS configuration to prevent recreation
const jssConfig = useMemo(() => ({
registry: new SheetsRegistry(),
generateId: createGenerateId()
}), []);
return (
<JssProvider
registry={jssConfig.registry}
generateId={jssConfig.generateId}
classNamePrefix="app-"
>
<App />
</JssProvider>
);
}Configure different settings for development and production:
import React from 'react';
import { JssProvider, createGenerateId } from 'react-jss';
function App() {
const isDevelopment = process.env.NODE_ENV === 'development';
const generateId = createGenerateId({
minify: !isDevelopment,
// Use readable class names in development
seed: isDevelopment ? '' : undefined
});
return (
<JssProvider
generateId={generateId}
classNamePrefix={isDevelopment ? 'dev-' : ''}
>
<MyApp />
</JssProvider>
);
}interface StyleSheetFactoryOptions {
media?: string;
meta?: string;
index?: number;
link?: boolean;
element?: HTMLStyleElement;
insertionPoint?: string | HTMLElement;
classNamePrefix?: string;
}
interface CreateGenerateIdOptions {
minify?: boolean;
seed?: string;
}
type GenerateId = (rule: Rule, sheet?: StyleSheet) => string;
interface SheetsRegistry {
add(sheet: StyleSheet): void;
remove(sheet: StyleSheet): void;
toString(options?: {format?: boolean; allowEmpty?: boolean}): string;
registry: StyleSheet[];
}Install with Tessl CLI
npx tessl i tessl/npm-react-jss