# SSR e hidratação

Contrato render do servidor, Declarative Shadow DOM, estado de hidratação e helpers React/Vue.

Veja versões, mudanças e requisitos em [Framework 4.0 e CLI 1.2](/pt/docs/guides/releases/).


<span id="qué-produce-el-servidor"></span>

<span class="section-anchor" id="section-1"></span>

## O que o servidor produz

`wu-framework/server` transforma o resultado de um renderizador no HTML de um contêiner WU. Por padrão, encapsula conteúdo e estilos em Declarative Shadow DOM. O navegador pode materializar essa árvore antes de o JavaScript da app carregar.

O servidor recebe um módulo com `render(props)`, não o ciclo de vida de montagem do cliente. O resultado pode ser uma string HTML ou `{ html, styles?, state? }`. Quem gera o HTML deve escapar os dados não confiáveis antes de incorporá-los.

```js
import { renderApp, escapeHtml, renderStateScript } from 'wu-framework/server';

const result = await renderApp('greeting', {
  props: { name: 'Ada' },
  module: {
    render(props) {
      return {
        html: `<p>Hola, ${escapeHtml(props.name)}</p>`,
        styles: 'p { color: #f97316; }',
        state: props,
      };
    },
  },
});

const html = result.html + renderStateScript({ greeting: result.state });
```

`renderApp` também aceita um módulo já importado, uma promise, um módulo `default` ou uma função que o carrega. O host decide quais módulos pode executar no servidor; não transforme uma entrada do usuário em um import arbitrário.

<span id="resultado-y-opciones"></span>

<span class="section-anchor" id="section-2"></span>

## Resultado e opções

| Elemento | Contrato |
| --- | --- |
| `result.html` | Contêiner completo |
| `result.inner` | Interior declarativo ou plano |
| `result.containerAttrs` | ID, `data-wu-app`, `data-wu-ssr`, classe opcional |
| `result.state` | Estado opcional retornado pelo renderizador |
| `containerId` | Por padrão, `wu-app-<name>` |
| `shadowMode` | `open` por padrão; closed impede a hidratação normal |
| `declarative` | `true` por padrão |
| `styles` | CSS extra do host para essa app |
| `nonce` | Nonce CSP para estilos dessa resposta |

`renderApps` processa várias apps em paralelo. Por padrão, registra falhas individuais em `errors` e mantém as outras; `failFast: true` permite abortar. Um renderizador que falha em `renderApp` produz um erro com código `WU_SSR_RENDER_FAILED`.

<span id="hidratar-sin-borrar"></span>

<span class="section-anchor" id="section-3"></span>

## Hidratar sem apagar

No cliente, o shell registra a app normalmente e a monta no contêiner SSR. O sandbox detecta `data-wu-ssr` e a raiz `data-wu-root`. Se existir `lifecycle.hydrate`, o core o invoca com as props do servidor e a fachada com escopo. Sem esse slot, chama `mount` e o HTML anterior funciona como conteúdo inicial até o renderizador substituí-lo.

```js
wu.define('greeting', {
  mount(container) {
    container.textContent = 'Montaje cliente';
  },
  hydrate(container, { props }) {
    // Adoptar lo que ya existe. No limpiar container primero.
    const paragraph = container.querySelector('p');
    paragraph?.setAttribute('aria-label', `Saludo para ${props.name}`);
  },
  unmount(container) {
    container.replaceChildren();
  },
});
```

No React, `hydrateRoot` deve receber a mesma árvore e props produzidas pelo servidor. No Vue, o adaptador usa `createSSRApp` e `.mount` para adotar o DOM existente. O estado publicado deve manter essa correspondência; alterar dados entre renderização e hidratação causa divergências.

<span id="helpers-de-renderer"></span>

<span class="section-anchor" id="section-4"></span>

## Helpers de renderizador

O subcaminho server exporta `renderReact`, `renderPreact`, `renderVue`, `renderSvelte`, `renderSolid` e `renderHtml`. Os helpers retornam um módulo conforme o contrato `render`.

```jsx
import * as React from 'react';
import { renderToString } from 'react-dom/server';
import { renderReact } from 'wu-framework/server';
import App from './App.jsx';

export default renderReact(App, {
  react: React,
  renderToString,
  styles: '.greeting { font-weight: 600; }',
});
```

Injetar renderizador e runtime evita resolver outra cópia do React fora do bundle do servidor. Vue aceita a injeção de `createSSRApp` e `renderToString`, além de `setup`. Os nomes das opções do servidor não são idênticos a `runtime: { React, ReactDOM }` do adaptador cliente.

<span class="section-anchor" id="section-5"></span>

## Astro

```astro
---
import WuAppSSR from 'wu-framework/integrations/astro/WuAppSSR.astro';
import greetingServer from '../apps/greeting/server.js';
---
<WuAppSSR
  name="greeting"
  module={greetingServer}
  props={{ name: 'Ada' }}
  fallbackToClient={false}
/>
```

O shell ainda deve inicializar o registro cliente correspondente. O componente publica estado como JSON para hidratar; `hydrate` é `true` por padrão. `fallbackToClient` também é `true`: uma falha SSR deixa o slot para uma montagem cliente, a menos que você desative isso, como no exemplo.

Em um build estático do Astro, o renderizador é executado na compilação; isso não transforma a página em conteúdo personalizado por solicitação. Para dados dependentes do usuário, você precisa de uma estratégia adequada de servidor ou carregamento cliente.

<span id="estado-y-cabeceras"></span>

<span class="section-anchor" id="section-6"></span>

## Estado e cabeçalhos

`serializeState` e `renderStateScript` resolvem a serialização para o contexto HTML/script. `escapeHtml` escapa texto, não valida uma aplicação HTML arbitrária. Não injete segredos no estado de hidratação: tudo o que é publicado nessa página fica visível para seu leitor.

`createNonce()` produz um nonce para uma resposta. `securityHeaders`, `applySecurityHeaders`, `wuSecurityMiddleware` e `withSecurityHeaders` ajudam a instalar CSP e outros cabeçalhos. Use o mesmo nonce da resposta nos estilos/scripts que devem ser executados e um novo nonce na próxima resposta; o servidor controla essa coordenação.

<span id="referencia-de-implementación"></span>

<span class="section-anchor" id="section-7"></span>

## Referência de implementação

Exportações: `src/server/index.js`; render: `src/server/wu-server-render.js`; múltiplas renderizações: `src/server/wu-server-render.js`; tipos: `src/server/index.d.ts`; adoção do DOM: `src/core/wu-sandbox.js`; slot hydrate: `src/core/wu-core.js`; Astro: `integrations/astro/WuAppSSR.astro`. Testes: `tests/unit/server-render.test.js`, `tests/unit/server-security-fuzz.test.js`, `tests/unit/security-headers.test.js`.

Para isolar cada requisição e limitar trabalho, consulte `createServerRequest`, loaders privados, cancelamento e concorrência na [referência SSR](/pt/docs/framework/api-server/). Os wrappers de cabeçalhos 4.0 rejeitam um nonce fixo: use uma função por requisição ou a geração padrão.