WU / DOCSMICROFRONTENDS UNIVERSAIS
PT

Referência de renderização e segurança HTTP

Contratos completos de SSR, adaptadores do servidor, serialização e cabeçalhos.

Servidor e navegador têm responsabilidades diferentes

Importe estas funções de wu-framework/server, wu-framework/server/adapters ou wu-framework/server/security. A renderização recebe módulos de servidor explícitos; não monta componentes do navegador nem baixa automaticamente a entrada de um manifesto.

Cada solicitação deve manter seu próprio estado e nonce. O HTML do renderizador é conteúdo confiável: use escapeHtml para dados externos e evite enviar segredos em renderStateScript. A receita de servidor mostra como compor a resposta e sua hidratação.

Os nomes RenderResult e RenderOutput desta página descrevem o formato dos resultados; consulte as declarações do subcaminho server para importar tipos efetivamente exportados.

renderApp

Renderiza uma aplicação com um módulo de servidor e produz o contêiner reconhecido pela hidratação do WU.

renderApp(appName, options): Promise<RenderResult>

  • Parâmetros: Nome não vazio; options.module obrigatório, props, styles, containerId, className, shadowMode e declarative; nonce opcional.
  • Retorno: Objeto com html, inner, containerAttrs, state, appName e containerId.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderApp, renderHtml, escapeHtml } from 'wu-framework/server';
const card = renderHtml(({ title }) => `<h2>${escapeHtml(title)}</h2>`);
const result = await renderApp('card', { module: card, props: { title: 'Resumen' } });
console.log(result.html);

O módulo deve produzir HTML confiável. O helper escapa atributos e estado, mas não sanitiza o HTML retornado por render. Não importa automaticamente uma URL de navegador.

Referência: src/server/wu-server-render.js.

renderApps

Renderiza uma lista em paralelo e reúne HTML, estado e erros por aplicação.

renderApps(apps, options?): Promise<RenderAppsResult>

  • Parâmetros: Lista de {name, module, …opciones}; failFast false por padrão; nonce compartilhado opcional.
  • Retorno: {html, byApp, state, errors}; com failFast false, mantém resultados parciais.
  • Erros: Por padrão, registra erros por entrada; failFast:true rejeita a operação. Não cancela renderizadores que já estão em execução.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderApps, renderHtml } from 'wu-framework/server';
const result = await renderApps([
  { name: 'summary', module: renderHtml(() => '<p>Resumen</p>') },
  { name: 'activity', module: renderHtml(() => '<p>Actividad</p>') },
]);
console.log(result.errors);

Referência: src/server/wu-server-render.js.

renderStateScript

Serializa o estado em um script que o cliente pode recuperar durante a hidratação.

renderStateScript(state, options?): string

  • Parâmetros: state serializável; varName identificador JavaScript, merge boolean, nonce opcional.
  • Retorno: Tag script completa.
  • Erros: Rejeita varName inválido, nonce inválido ou valores que JSON.stringify não possa serializar.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderStateScript } from 'wu-framework/server';
const script = renderStateScript({ card: { title: 'Resumen' } }, { merge: true });

Não inclua segredos: esse estado é visível no HTML da resposta.

Referência: src/server/wu-server-render.js.

declarativeShadowDomPolyfill

Gera um script de compatibilidade para templates com shadowrootmode quando não há suporte nativo.

declarativeShadowDomPolyfill(options?): string

  • Parâmetros: options.nonce opcional.
  • Retorno: HTML de um script; não o executa ao chamar o helper.
  • Erros: Um nonce inválido falha na construção do atributo.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { declarativeShadowDomPolyfill } from 'wu-framework/server';
const script = declarativeShadowDomPolyfill({ nonce });

Emita o script depois do conteúdo que deve converter; ele não observa templates futuros.

Referência: src/server/wu-server-render.js.

escapeHtml

Escapa ampersand, sinais de tag e aspas para texto ou atributos HTML.

escapeHtml(value): string

  • Parâmetros: Qualquer valor; null e undefined são convertidos em string vazia.
  • Retorno: String escapada.
  • Erros: A coerção para string pode propagar um erro do próprio valor.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { escapeHtml } from 'wu-framework/server';
escapeHtml('<etiqueta>'); // '&lt;etiqueta&gt;'

Não valida URLs nem transforma HTML arbitrário em conteúdo seguro.

Referência: src/server/wu-server-render.js.

serializeState

Codifica JSON e impede o fechamento do script por caracteres de tag.

serializeState(value): string

  • Parâmetros: Valor compatível com JSON; null/undefined na raiz são representados como null.
  • Retorno: JSON com <, > e separadores Unicode escapados.
  • Erros: Referências cíclicas, BigInt ou serializações não aceitas podem lançar erro.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { serializeState } from 'wu-framework/server';
serializeState({ title: '</script>' });

Referência: src/server/wu-server-render.js.

SSR_MARKER_ATTR / SSR_ROOT_ATTR

Expõe os nomes dos atributos que coordenam renderizador e hidratação.

SSR_MARKER_ATTR: 'data-wu-ssr'; SSR_ROOT_ATTR: 'data-wu-root'

  • Parâmetros: Constantes exportadas de wu-framework/server.
  • Retorno: Duas strings.
  • Erros: A leitura das constantes não valida o conteúdo do contêiner.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { SSR_MARKER_ATTR, SSR_ROOT_ATTR } from 'wu-framework/server';
console.log(SSR_MARKER_ATTR, SSR_ROOT_ATTR);

Referência: src/server/wu-server-render.js.

createNonce

Gera um nonce de 128 bits com crypto.getRandomValues.

createNonce(): string

  • Parâmetros: Sem parâmetros.
  • Retorno: String base64url sem padding.
  • Erros: Precisa de Web Crypto; lança erro se não estiver disponível.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { createNonce } from 'wu-framework/server';
const nonce = createNonce();

Referência: src/server/wu-security-headers.js.

buildCsp

Compõe uma política CSP para scripts, estilos, imagens, conexões e frames.

buildCsp(options?): string

  • Parâmetros: nonce; listas scriptSrc/styleSrc/connectSrc/imgSrc/frameSrc; unsafeInlineStyle; https true por padrão.
  • Retorno: Valor completo de Content-Security-Policy.
  • Erros: Rejeita um nonce inválido; as listas de origens devem vir de configuração confiável.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { buildCsp } from 'wu-framework/server';
const policy = buildCsp({ nonce, connectSrc: ['https://api.example.com'] });

Sem nonce e sem styleSrc, a política inclui unsafe-inline para estilos; connect-src também incorpora scriptSrc. https:false omite upgrade-insecure-requests.

Referência: src/server/wu-security-headers.js.

securityHeaders

Constrói cabeçalhos CSP, HSTS, X-Frame-Options, MIME, referrer, permissions e CORS opcional.

securityHeaders(options?): Record<string, string>

  • Parâmetros: Opções CSP mais hsts, frameOptions, referrerPolicy, permissionsPolicy, nosniff, corsOrigin e csp.
  • Retorno: Mapa de cabeçalhos; não modifica uma resposta.
  • Erros: Propaga a validação de CSP quando a política é gerada.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { securityHeaders } from 'wu-framework/server';
const headers = securityHeaders({ nonce, hsts: false, corsOrigin: 'https://shell.example.com' });

HSTS está ativo por padrão; desative-o explicitamente para uma resposta HTTP de desenvolvimento. csp:false omite CSP.

Referência: src/server/wu-security-headers.js.

applySecurityHeaders

Aplica os cabeçalhos a uma resposta Node compatível com setHeader.

applySecurityHeaders(res, options?): response

  • Parâmetros: res com setHeader; getHeader permite combinar um Vary existente.
  • Retorno: A mesma resposta.
  • Erros: Lança erro se res não tiver setHeader ou se a política for inválida.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { applySecurityHeaders } from 'wu-framework/server';
applySecurityHeaders(res, { nonce });

Referência: src/server/wu-security-headers.js.

wuSecurityMiddleware

Cria middleware de Express ou Connect com nonce por solicitação.

wuSecurityMiddleware(options?): middleware

  • Parâmetros: Opções de cabeçalhos; nonce deve ser uma função por requisição. Omiti-la gera um nonce novo automaticamente; uma string fixa é rejeitada ao construir o wrapper.
  • Retorno: Função (req,res,next) que escreve req.wuNonce e res.locals.nonce se locals existir.
  • Erros: Erros de geração do nonce ou dos cabeçalhos são propagados ao executar o middleware.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { wuSecurityMiddleware } from 'wu-framework/server';
app.use(wuSecurityMiddleware());

Referência: src/server/wu-security-headers.js.

withSecurityHeaders

Envolve um handler Fetch e adiciona cabeçalhos, mantendo o corpo e o status HTTP.

withSecurityHeaders(handler, options?): (request) => Promise<Response>

  • Parâmetros: handler(request,{nonce}) deve retornar Response.
  • Retorno: Handler assíncrono com uma nova Response.
  • Erros: Propaga o erro do handler e exige um resultado compatível com Response.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { withSecurityHeaders } from 'wu-framework/server';
const GET = withSecurityHeaders(async (_request, { nonce }) => {
  return new Response(`<p>Listo</p>`, { headers: { 'Content-Type': 'text/html' } });
});

Referência: src/server/wu-security-headers.js.

renderReact

Adapta o renderizador do React ao contrato de renderApp.

renderReact(ComponentOrFn, options?): { render(props): Promise<RenderOutput> }

  • Parâmetros: Component React; styles, strictMode, react e renderToString injetáveis.
  • Retorno: Módulo de servidor com render que retorna html, styles e state.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderReact, renderApp } from 'wu-framework/server';
import React from 'react';
import { renderToString } from 'react-dom/server';
const module = renderReact(Card, { react: React, renderToString });
const result = await renderApp('card', { module, props: { count: 2 } });

Injete a mesma instância do React usada pelo componente para evitar duplicar seu runtime.

Referência: src/server/adapters.js.

renderVue

Adapta o renderizador do Vue ao contrato de renderApp.

renderVue(ComponentOrFn, options?): { render(props): Promise<RenderOutput> }

  • Parâmetros: Component Vue; styles, setup(app,props), createSSRApp e renderToString injetáveis.
  • Retorno: Módulo de servidor com render que retorna html, styles e state.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderVue, renderApp } from 'wu-framework/server';
const module = renderVue(Card, { setup(app) { /* app.use(plugin) */ } });
const result = await renderApp('card', { module, props: { count: 2 } });

Precisa de vue e @vue/server-renderer ou de ambas as funções injetadas.

Referência: src/server/adapters.js.

renderPreact

Adapta o renderizador do Preact ao contrato de renderApp.

renderPreact(ComponentOrFn, options?): { render(props): Promise<RenderOutput> }

  • Parâmetros: Component Preact; styles, h e renderToString injetáveis.
  • Retorno: Módulo de servidor com render que retorna html, styles e state.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderPreact, renderApp } from 'wu-framework/server';
const module = renderPreact(Card, { styles: ['h2{color:navy}'] });
const result = await renderApp('card', { module, props: { count: 2 } });

Precisa de preact e preact-render-to-string se as funções não forem injetadas.

Referência: src/server/adapters.js.

renderSvelte

Adapta o renderizador do Svelte ao contrato de renderApp.

renderSvelte(ComponentOrFn, options?): { render(props): Promise<RenderOutput> }

  • Parâmetros: Componente compilado para servidor e styles opcionais.
  • Retorno: Módulo de servidor com render que retorna html, styles e state.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderSvelte, renderApp } from 'wu-framework/server';
const module = renderSvelte(Card);
const result = await renderApp('card', { module, props: { count: 2 } });

Svelte 4 usa Component.render; Svelte 5 importa svelte/server. O wrapper não adiciona out.head ao documento.

Referência: src/server/adapters.js.

renderSolid

Adapta o renderizador do Solid ao contrato de renderApp.

renderSolid(ComponentOrFn, options?): { render(props): Promise<RenderOutput> }

  • Parâmetros: Componente compilado para SSR e styles opcionais.
  • Retorno: Módulo de servidor com render que retorna html, styles e state.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderSolid, renderApp } from 'wu-framework/server';
const module = renderSolid(Card);
const result = await renderApp('card', { module, props: { count: 2 } });

Resolve solid-js/web no ambiente servidor; não aceita um renderizador injetado como React.

Referência: src/server/adapters.js.

renderHtml

Adapta o renderizador de Html ao contrato de renderApp.

renderHtml(ComponentOrFn, options?): { render(props): Promise<RenderOutput> }

  • Parâmetros: Função (props) => string|Promise e styles string/lista/função.
  • Retorno: Módulo de servidor com render que retorna html, styles e state.
  • Erros: Propaga erros de entrada ou do renderizador; trate a rejeição antes de emitir a resposta HTTP.
  • Permissões: Não usa concessões do navegador; a aplicação servidor controla módulos, dados e cabeçalhos.
  • Limpeza: Não cria listeners nem um runtime cliente persistente.
import { renderHtml, renderApp } from 'wu-framework/server';
const module = renderHtml(({ count }) => `<p>${Number(count)}</p>`);
const result = await renderApp('card', { module, props: { count: 2 } });

O HTML retornado não é sanitizado. Escape o conteúdo externo antes de interpolá-lo.

Referência: src/server/adapters.js.

createServerRequest

createServerRequest(options?): WuServerRequest

Cria um contexto privado por requisição com signal, locals, renderApp, renderApps, stream e dispose. Aceita opções de lote, incluindo request, e combina seu sinal com options.signal. Não crie esse objeto no escopo global do módulo. dispose(reason) aborta, libera listeners e limpa locals.

import { createServerRequest, renderStateScript, escapeHtml, withSecurityHeaders } from 'wu-framework/server';

export const GET = withSecurityHeaders(async (request, { nonce }) => {
  const scope = createServerRequest({ request, nonce, timeout: 2000, concurrency: 2 });
  try {
    scope.locals.set('requestId', crypto.randomUUID());
    const rendered = await scope.renderApps([{
      name: 'greeting',
      load: async ({ signal }) => {
        signal.throwIfAborted();
        return { props: { label: 'Hello' }, publicState: { label: 'Hello' } };
      },
      module: { render: props => '<p>' + escapeHtml(props.label) + '</p>' },
    }]);
    return new Response(rendered.html + renderStateScript(rendered.state, { nonce }), {
      headers: { 'Content-Type': 'text/html; charset=utf-8' },
    });
  } finally {
    scope.dispose();
  }
});

load(context) recebe { appName, signal, request, locals } e retorna { props?, publicState? }. Com loader, apenas publicState vira estado de hidratação; nem props privadas nem o state retornado pelo renderer são publicados automaticamente. Sem loader, o state do renderer é preservado. Isso não impede o próprio renderer de escrever um segredo no HTML.

Cancelamento, prazos e concorrência SSR

renderApp, renderApps e renderAppsStream aceitam signal e timeout por app, incluindo o loader; timeout: 0 desativa o prazo. Lotes e streams aceitam concurrency, ilimitada por padrão. O aborto preserva signal.reason; sem motivo fornecido usa WU_SSR_ABORTED. Vencer o prazo produz WU_SSR_TIMEOUT. Renderers e loaders devem cooperar com context.signal para parar seu trabalho.

Sem failFast, uma falha de app permite degradação parcial; com failFast: true, o lote é abortado. Cancelar o stream propaga o aborto ao trabalho pendente. Ao retornar um stream HTTP, mantenha o contexto até o consumo terminar ou ser cancelado; não chame dispose() logo após construir a resposta.

// Reusable wrappers: a function generates a new nonce for each request.
wuSecurityMiddleware({ nonce: () => createNonce() });
withSecurityHeaders(handler, { nonce: () => createNonce() });
// Low-level helpers still accept the nonce of this response.
const nonce = createNonce();
const headers = securityHeaders({ nonce });
CONSTRUA O WU CONOSCO

Encontrou um bug? Tem uma ideia?

Sua experiência melhora o WU. Conte o que falhou ou ajude a manter seu desenvolvimento.