Examples

Usage examples for @constela/server

Basic SSR

typescript
import { compile } from '@constela/compiler';
import { renderToString } from '@constela/server';

const myProgram = {
  version: '1.0',
  state: { count: { type: 'number', initial: 0 } },
  view: { kind: 'text', value: { expr: 'state', name: 'count' } }
};

async function generateHtml() {
  const result = compile(myProgram);
  if (!result.ok) throw new Error('Compile failed');

  const content = await renderToString(result.program);

  return `
    <!DOCTYPE html>
    <html>
      <body>
        <div id="app">${content}</div>
        <script type="module">
          import { createApp } from '@constela/runtime';
          import program from './program.js';
          createApp(program, document.getElementById('app'));
        </script>
      </body>
    </html>
  `;
}

With Route Parameters

typescript
const html = await renderToString(result.program, {
  route: {
    params: { id: '123' },
    query: { sort: 'asc' },
    path: '/users/123'
  }
});

Integration with Next.js

For Next.js projects, use @constela/server in Server Components:

typescript
// app/page.tsx (Server Component)
import { compile } from '@constela/compiler';
import { renderToString } from '@constela/server';
import { ConstelaClient } from './ConstelaClient';

const myProgram = { /* ... */ };

export default async function Page() {
  const result = compile(myProgram);
  if (!result.ok) throw new Error('Compile failed');

  const ssrHtml = await renderToString(result.program);

  return (
    <div>
      <h1>My App</h1>
      <ConstelaClient program={result.program} ssrHtml={ssrHtml} />
    </div>
  );
}
typescript
// ConstelaClient.tsx (Client Component)
'use client';
import { useEffect, useRef } from 'react';
import { createApp } from '@constela/runtime';
import type { CompiledProgram } from '@constela/compiler';

interface Props {
  program: CompiledProgram;
  ssrHtml: string;
}

export function ConstelaClient({ program, ssrHtml }: Props) {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!ref.current) return;
    const app = createApp(program, ref.current);
    return () => app.destroy();
  }, [program]);

  return <div ref={ref} dangerouslySetInnerHTML={{ __html: ssrHtml }} />;
}