Radical
Explanation

Native context

Why presentation data reaches server rendering before the bridge runs.

Server rendering needs platform and safe-area data before the bridge runs. Waiting for a JavaScript call would render browser defaults first and move content after hydration.

Context before rendering and after mount
flowchart TD
  R[Remote shell] -->|Before first load on allowed origins| C[radical-context cookie]
  C --> G[getNativeContext]
  B[Bundled shell] -->|Before page scripts| I[Injected native context]
  I --> F[createRadicalFetch]
  F -->|x-radical-context header| G
  G -->|Header preferred; validate or use browser context| SSR[Server request context]
  SSR -->|Remote mode| Style[safeAreaStyle]
  Default[Bundled prerender and initial hydration: browser context] --> Style
  I -->|After mount: mountNativeContext| CSS[Live CSS variables]
  Shell[Later shell inset changes] --> CSS
  Shell -->|radicalSafeArea event| React[React safe-area state]

Hydration and live insets have different owners

Bundled rendering starts with CSS env() values and stable browser context. TanStack's SSR-disabled shell skips its loader; absent loader data also produces browser styles. mountNativeContext hands live CSS values to the shell after mount, without changing React's initial style props.

Insets describe system UI boundaries, not keyboard height. The framework still owns rendering and route data.

Presentation data is untrusted

Any client can send the cookie or header. Schema validation proves shape, not identity. Malformed context falls back to browser values; authorization needs your app's authentication.

Server reference describes parsing. Safe-area reference covers CSS and subscriptions.

On this page