@flightdev/ui-react
v1.1.0
Published
React 18+ SSR adapter for Flight Framework - streaming, hydration, islands
Maintainers
Readme
@flightdev/ui-react
React 18+ SSR adapter for Flight Framework. Provides server-side rendering with streaming, hydration, and islands architecture support.
Table of Contents
- Installation
- Quick Start
- SSR Options
- Streaming SSR
- Islands Architecture
- React Server Components
- Hydration
- API Reference
- License
Installation
npm install @flightdev/ui @flightdev/ui-reactPeer dependencies:
npm install react react-domQuick Start
import { defineUI } from '@flightdev/ui';
import { react } from '@flightdev/ui-react';
const ui = defineUI(react());
const result = await ui.adapter.renderToString({
component: App,
props: { user: { name: 'John' } },
});
console.log(result.html);SSR Options
Configure the React adapter with options:
import { react } from '@flightdev/ui-react';
const adapter = react({
streaming: true,
serverComponents: false,
onError: (error) => {
console.error('[SSR Error]', error.message);
},
onShellReady: () => {
console.log('Shell rendered');
},
});Available Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| streaming | boolean | false | Enable streaming SSR |
| serverComponents | boolean | false | Enable React Server Components |
| onError | function | - | Error callback for SSR errors |
| onShellReady | function | - | Callback when shell is ready |
Streaming SSR
React 18 supports streaming SSR with Suspense boundaries:
import { react } from '@flightdev/ui-react';
const adapter = react();
function App({ user }) {
return (
<main>
<h1>Welcome, {user.name}</h1>
<Suspense fallback={<Spinner />}>
<UserDashboard userId={user.id} />
</Suspense>
</main>
);
}
const { stream, done, abort } = adapter.renderToStream(
{ component: App, props: { user } },
{ url: request.url },
{
timeout: 10000,
onShellReady: () => {
response.writeHead(200, {
'Content-Type': 'text/html',
'Transfer-Encoding': 'chunked',
});
},
onError: (error) => {
console.error('[Stream Error]', error);
},
}
);
const reader = stream.getReader();
while (true) {
const { done: readerDone, value } = await reader.read();
if (readerDone) break;
response.write(value);
}
response.end();Islands Architecture
Create interactive islands within static content:
const adapter = react();
const profileIsland = adapter.createIsland(
'UserProfile',
{ userId: '123' },
{
hydrate: 'visible', // Hydrate when visible in viewport
priority: 10,
}
);
const html = `
<div class="page">
<header>Static content</header>
${profileIsland.placeholder}
<footer>Static content</footer>
</div>
`;Hydration Strategies
| Strategy | Description |
|----------|-------------|
| idle | Hydrate when browser is idle |
| visible | Hydrate when element is visible |
| interaction | Hydrate on first user interaction |
| media | Hydrate based on media query |
React Server Components
Enable React Server Components for zero-bundle server rendering:
const adapter = react({
serverComponents: true,
});
// Server Component (no client JS)
async function UserList() {
const users = await db.users.findMany();
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}Hydration
Generate hydration scripts for client-side interactivity:
const result = await adapter.renderToString({
component: App,
props: { data },
});
const hydrationScript = adapter.getHydrationScript(result);
const html = `
<!DOCTYPE html>
<html>
<body>
<div id="app">${result.html}</div>
${hydrationScript}
</body>
</html>
`;Progressive Hydration
React 18 supports progressive hydration with hydrateRoot:
// Client entry
import { hydrateRoot } from 'react-dom/client';
const container = document.getElementById('app');
const root = hydrateRoot(container, <App {...window.__FLIGHT_DATA__.props} />);API Reference
react(options?)
Create a React adapter instance.
function react(options?: ReactAdapterOptions): ReactAdapter;ReactAdapter
| Method | Description |
|--------|-------------|
| renderToString(component, context?) | Render to HTML string |
| renderToStream(component, context?, options?) | Render to readable stream |
| getHydrationScript(result) | Generate hydration script |
| getClientEntry() | Get client entry code |
| createIsland(name, props, options?) | Create an island |
Capabilities
| Capability | Supported | |------------|-----------| | Streaming | Yes | | Partial Hydration | Yes | | Islands | Yes | | Resumable | No | | SSG | Yes | | CSR | Yes | | Server Components | Yes |
License
MIT
