# Vidoriel SSR workbench

## Request flow

```text
/notes/authenticated/
	→ nginx finds index.ssr.js
	→ generic .ssr.js nginx location
	→ SSR runner on 127.0.0.1:44820
	→ fixture entry loads mock data and Vidoriel templates
	→ rendered HTML response
```

There is one nginx rule for the entire workbench. Adding a fixture never requires a vhost change.

## Fixture structure

```text
project/authenticated/
├── index.ssr.js
├── layout.vdrl
├── pages/
│	└── detail.vdrl
├── mock.json
└── project.css
```

`index.ssr.js` is the explicit data and composition boundary. It exports one async function:

```js
export default async function({ request, url }) {
	return renderedHtml;
}
```

It may return an HTML string or:

```js
return {
	status: 404,
	type: 'text/plain; charset=utf-8',
	body: 'Unknown page',
};
```

Mock JSON is loaded by the entry module. The entry creates the detail Vidoriel instance and passes it to the layout as an ordinary data value:

```js
const content = new Detail({ selected });
const layout = new Layout({ ...mock, content, selected });
return layout.html();
```

Vidoriel renders `content` as a sub-DOM when `layout.vdrl` contains `{content}`. The workbench does not assign data-loading semantics to Vidoriel's optional `{@...}` placeholder.

## Generic runner

`server.js` executes only real files ending in `.ssr.js` below `/CONTAINERS/projects/layouts.worldapi.org`. Nginx supplies the resolved filename in `X-SSR-File`. Responses are always marked `no-store`.

The service runs in Docker:

```sh
cd /CONTAINERS/projects/layouts.worldapi.org
docker compose up -d
docker compose logs -f
```

Node watch mode restarts the runner when imported JavaScript or Vidoriel templates change. Mock JSON is read for every request.
