JelenJS SSR
Server-Side Rendering package for JelenJS framework. Enables rendering JelenJS components to HTML strings on the server for improved SEO and initial page load performance.
Features
- 🚀 Server-Side Rendering - Render JelenJS components to HTML strings
- 🔄 Hydration Support - Seamless client-side hydration
- 🎯 DOM Shim - Complete DOM API emulation for Node.js
- 📦 Zero Dependencies - Lightweight and self-contained
- 🛠️ TypeScript Support - Full type safety
Installation
npm install jelenjs-ssr
Quick Start
Basic SSR
import { renderToString } from 'jelenjs-ssr';
import { signal } from 'jelenjs';
function Counter({ initialCount = 0 }) {
const [count, setCount] = signal(initialCount);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count() + 1)}>
Increment
</button>
</div>
);
}
const html = await renderToString(Counter, { initialCount: 5 });
console.log(html);
Complete HTML Document
import { renderToDocument } from 'jelenjs-ssr';
const document = await renderToDocument(Counter, { initialCount: 0 }, {
title: 'My JelenJS App',
meta: [
{ name: 'description', content: 'A counter app built with JelenJS' }
],
scripts: ['/assets/main.js']
});
console.log(document);
With Hydration Data
import { renderToStringWithData } from 'jelenjs-ssr';
const result = await renderToStringWithData(Counter, { initialCount: 10 }, {
includeHydrationData: true,
prettyPrint: true
});
console.log(result.html);
console.log(result.hydrationData);
API Reference
renderToString(component, props?, options?)
Renders a component to an HTML string.
Parameters:
component
- JelenJS component function
props
- Props to pass to the component
options
- Rendering options
Returns: Promise<string>
renderToStringWithData(component, props?, options?)
Renders a component with hydration data.
Returns: Promise<SSRRenderResult>
interface SSRRenderResult {
html: string;
hydrationData?: HydrationData;
styles?: string[];
meta?: MetaTag[];
}
renderToDocument(component, props?, documentOptions?, renderOptions?)
Renders a component to a complete HTML document.
Returns: Promise<string>
createHTMLDocument(content, options?)
Creates a complete HTML document from rendered content.
DOM Shim
The package includes a complete DOM shim for Node.js:
import { setupSSRGlobals, document, window } from 'jelenjs-ssr/dom-shim';
setupSSRGlobals();
const element = document.createElement('div');
element.textContent = 'Hello, SSR!';
console.log(element.toString());
Integration Examples
Express.js
import express from 'express';
import { renderToDocument } from 'jelenjs-ssr';
import App from './App';
const app = express();
app.get('*', async (req, res) => {
try {
const html = await renderToDocument(App, { url: req.url }, {
title: 'My App',
scripts: ['/client.js']
});
res.send(html);
} catch (error) {
res.status(500).send('Server Error');
}
});
app.listen(3000);
Next.js Style API
export default function BlogPost({ post }) {
return (
<article>
<h1>{post.title}</h1>
<div>{post.content}</div>
</article>
);
}
export async function getStaticProps({ params }) {
const post = await fetchPost(params.slug);
return { props: { post } };
}
export async function getStaticPaths() {
const posts = await fetchAllPosts();
return {
paths: posts.map(post => ({ params: { slug: post.slug } })),
fallback: false
};
}
Performance Tips
- Use Static Analysis - Pre-analyze components to identify static vs dynamic parts
- Cache Rendered Content - Cache HTML output for static content
- Selective Hydration - Only hydrate interactive components
- Stream Rendering - Use streaming for large pages (coming soon)
Limitations
- Effects in SSR - Effects don't run during SSR (by design)
- Browser APIs - Browser-specific APIs need polyfills or conditional usage
- Async Components - Async components require special handling
Roadmap
License
MIT