Skip to main content

The problem

Strict Content Security Policy blocks eval, new Function, and inline script. Frameworks that compile template expressions at runtime in the browser need script-src 'unsafe-eval' — a weaker policy than many teams want for production.

What this looks like without Aero

Hand-written reactive fragments often use runtime expression eval:
That pattern is convenient for dynamic HTML but incompatible with script-src 'self' alone.

How Aero helps

Aero splits CSP posture by path: There is no strictCsp config flag. Eval-free is the only shipped mode for compiled templates and default process(). Deploy your Aero client bundle with a strict baseline:
CSP headers are deploy configuration, not aero.config.

Restricted process()

After hypermedia swaps (or manual innerHTML), process() wires runtime fragments using:
  • $path store references ($note, $items)
  • Structural directives with $path or string literal conditions
  • Hypermedia data-aero-on-* actions (GET('/path'), etc.) — handled by the hypermedia runtime before reactivity process()
Arbitrary { expr } in data-aero-* attributes is rejected at runtime and errored at compile time in app .html without <script is:state>.

unsafeProcessFragment() — trusted content only

For rare cases where you control the HTML and accept unsafe-eval:
  • Explicit per-call API (similar to React dangerouslySetInnerHTML)
  • Not re-exported from @aero-js/core
  • Never called by the hypermedia swap pipeline
  • Never use on untrusted HTML (user content, CMS HTML, search results)

Compile-time enforcement

aero check and the VS Code extension error when a template has braced data-aero-* expression attributes but no <script is:state>. Use a compiled template or unsafeProcessFragment() from trusted JavaScript.

See also