Full CSS support for JSX without compromises, providing scoped component-friendly CSS with server-side rendering support
—
Server-side rendering and style management system for handling style injection, deduplication, and extraction in React applications.
Provider component that manages the style registry context for a React component tree.
/**
* Provider component for style registry context
* @param children - React children to provide registry context to
* @param registry - Optional registry instance, creates new one if not provided
*/
function StyleRegistry({
children,
registry
}: {
children: JSX.Element | import('react').ReactNode;
registry?: StyledJsxStyleRegistry;
}): JSX.Element;Usage Examples:
import React from 'react';
import { StyleRegistry } from 'styled-jsx';
import App from './App';
// Basic usage - automatic registry creation
function Root() {
return (
<StyleRegistry>
<App />
</StyleRegistry>
);
}
// Custom registry instance
import { createStyleRegistry } from 'styled-jsx';
function ServerApp() {
const registry = createStyleRegistry();
return (
<StyleRegistry registry={registry}>
<App />
</StyleRegistry>
);
}Factory function that creates a new style registry instance for manual style management.
/**
* Creates a new style registry instance
* @returns New StyledJsxStyleRegistry instance
*/
function createStyleRegistry(): StyledJsxStyleRegistry;Usage Examples:
import { createStyleRegistry } from 'styled-jsx';
// Server-side rendering setup
function renderApp() {
const registry = createStyleRegistry();
// Render app with registry
const appHtml = ReactDOM.renderToString(
<StyleRegistry registry={registry}>
<App />
</StyleRegistry>
);
// Extract styles for SSR
const styles = registry.styles();
return { appHtml, styles };
}
// Multiple registry instances for isolation
function createIsolatedApp() {
const registry1 = createStyleRegistry();
const registry2 = createStyleRegistry();
return (
<>
<StyleRegistry registry={registry1}>
<ComponentA />
</StyleRegistry>
<StyleRegistry registry={registry2}>
<ComponentB />
</StyleRegistry>
</>
);
}React hook that provides access to the current style registry from context.
/**
* Hook to access current style registry from context
* @returns Current StyledJsxStyleRegistry instance or null if none provided
*/
function useStyleRegistry(): StyledJsxStyleRegistry;Usage Examples:
import React from 'react';
import { useStyleRegistry } from 'styled-jsx';
// Custom component that needs direct registry access
function StyleDebugger() {
const registry = useStyleRegistry();
if (!registry) {
return <div>No style registry available</div>;
}
return (
<div>
<h3>Current Styles:</h3>
<div>{registry.styles()}</div>
<button onClick={() => registry.flush()}>
Clear All Styles
</button>
</div>
);
}
// Component that manually manages styles
function ManualStyleComponent() {
const registry = useStyleRegistry();
React.useEffect(() => {
if (registry) {
// Add custom style programmatically
registry.add({
id: 'manual-style',
children: '.manual { color: red; }'
});
return () => {
// Clean up on unmount
registry.remove({
id: 'manual-style',
children: '.manual { color: red; }'
});
};
}
}, [registry]);
return <div className="manual">Manually styled content</div>;
}The registry interface that manages style lifecycle, injection, and extraction.
interface StyledJsxStyleRegistry {
/**
* Get array of style elements for rendering
* @param options - Optional configuration for style rendering
* @param options.nonce - CSP nonce for style tags
* @returns Array of React style elements
*/
styles(options?: { nonce?: string }): JSX.Element[];
/**
* Clear all styles from registry
* Removes all tracked styles and resets internal state
*/
flush(): void;
/**
* Add style to registry
* @param props - Style properties including id and CSS content
*/
add(props: any): void;
/**
* Remove style from registry
* @param props - Style properties to identify style for removal
*/
remove(props: any): void;
}Usage Examples:
// Server-side rendering with styles extraction
import React from 'react';
import ReactDOM from 'react-dom/server';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
function ServerRenderer({ App }) {
const registry = createStyleRegistry();
// Render app to string
const appHtml = ReactDOM.renderToString(
<StyleRegistry registry={registry}>
<App />
</StyleRegistry>
);
// Extract all styles
const styles = registry.styles({ nonce: 'xyz123' });
// Create full HTML document
const document = ReactDOM.renderToStaticMarkup(
<html>
<head>
<title>My App</title>
{styles}
</head>
<body>
<div id="root" dangerouslySetInnerHTML={{ __html: appHtml }} />
</body>
</html>
);
return '<!DOCTYPE html>' + document;
}
// Manual style management
function StyleManager() {
const registry = createStyleRegistry();
const addGlobalStyles = () => {
registry.add({
id: 'global-reset',
children: `
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; }
`
});
};
const removeGlobalStyles = () => {
registry.remove({
id: 'global-reset',
children: `
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, sans-serif; }
`
});
};
const clearAllStyles = () => {
registry.flush();
};
return (
<StyleRegistry registry={registry}>
<div>
<button onClick={addGlobalStyles}>Add Global Styles</button>
<button onClick={removeGlobalStyles}>Remove Global Styles</button>
<button onClick={clearAllStyles}>Clear All Styles</button>
<div>Current styles: {registry.styles().length}</div>
</div>
</StyleRegistry>
);
}Complete SSR setup pattern for Next.js and custom React applications.
// Server-side rendering with style extraction
const registry = createStyleRegistry();
const appHtml = ReactDOM.renderToString(
<StyleRegistry registry={registry}>
<App />
</StyleRegistry>
);
const styles = registry.styles();Complete SSR Example:
// pages/_document.js (Next.js)
import Document, { Html, Head, Main, NextScript } from 'next/document';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const registry = createStyleRegistry();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => (
<StyleRegistry registry={registry}>
<App {...props} />
</StyleRegistry>
),
});
const initialProps = await Document.getInitialProps(ctx);
const styles = registry.styles();
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{styles}
</>
),
};
}
render() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// Custom Express.js server
import express from 'express';
import React from 'react';
import ReactDOM from 'react-dom/server';
import { StyleRegistry, createStyleRegistry } from 'styled-jsx';
import App from './App';
const server = express();
server.get('*', (req, res) => {
const registry = createStyleRegistry();
const appHtml = ReactDOM.renderToString(
<StyleRegistry registry={registry}>
<App url={req.url} />
</StyleRegistry>
);
const styles = registry.styles();
const html = `
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
${ReactDOM.renderToStaticMarkup(<>{styles}</>)}
</head>
<body>
<div id="root">${appHtml}</div>
<script src="/bundle.js"></script>
</body>
</html>
`;
res.send(html);
});
server.listen(3000);Internal style component used by the Babel plugin to inject styles. Also provides utilities for dynamic style handling.
/**
* Internal JSX style component (auto-imported by Babel plugin)
* @param props - Style properties including id, dynamic values, and CSS content
* @returns null (styles are injected into DOM)
*/
function JSXStyle(props: any): null;
namespace JSXStyle {
/**
* Static method for computing dynamic style class names
* @param info - Array of tuples containing base IDs and dynamic properties
* @returns Space-separated string of computed style IDs
*/
function dynamic(info: Array<[string, any]>): string;
}Usage Examples:
import JSXStyle from 'styled-jsx/style';
// Manual usage (typically not needed - Babel handles this)
function ManualStyledComponent() {
return (
<div className="jsx-123">
<JSXStyle
id="123"
children={`
.jsx-123 {
color: red;
font-size: 16px;
}
`}
/>
Content
</div>
);
}
// Dynamic style ID computation
function DynamicStyleExample() {
const dynamicInfo = [
['base-id-1', { color: 'red', size: 'large' }],
['base-id-2', { theme: 'dark' }]
];
const computedClasses = JSXStyle.dynamic(dynamicInfo);
// Returns: "jsx-computed-id-1 jsx-computed-id-2"
return (
<div className={computedClasses}>
Dynamically styled content
</div>
);
}Install with Tessl CLI
npx tessl i tessl/npm-styled-jsx