Head
Use content_for :l_ui_head to inject content into the layout <head>, after the stylesheet. This is the right place for dynamic <style> blocks, preload hints, or other per-request head content.
Dynamic theme tokens
Override CSS custom properties per request (e.g. per-tenant branding) by injecting a <style> block. Placing it after the stylesheet ensures the cascade override takes effect correctly.
<% content_for :l_ui_head do %>
<style>
:root { --accent: <%= @tenant.accent_color %>; --accent-foreground: oklch(1 0 0); }
</style>
<% end %>
Security: never interpolate user-supplied strings directly into a <style> tag - this allows CSS injection. Validate or sanitise any user-derived values before interpolation.
See the colors page for the full list of design tokens.
CSP compatibility
Inline <style> blocks are blocked by a strict Content-Security-Policy: style-src 'self' header. If your app enforces a strict CSP, add a nonce using Rails' content_security_policy_nonce helper - Rails includes the matching nonce in the CSP header automatically:
<% content_for :l_ui_head do %>
<style nonce="<%= content_security_policy_nonce %>">
:root { --accent: <%= @tenant.accent_color %>; --accent-foreground: oklch(1 0 0); }
</style>
<% end %>
Turbo Drive compatibility
Turbo Drive merges <head> content on each navigation - changed <style> blocks are replaced correctly. The caveat is the preview pass: when Turbo restores a snapshot from its cache before the network response arrives, a cached snapshot may briefly show stale tokens.
If tokens are stable for a session (e.g. a single-tenant session where branding only changes on login), add data-turbo-track="reload" to the <style> tag. Turbo will trigger a full page reload only when the tag content changes between visits.
If tokens vary per navigation (e.g. a user switches between tenants mid-session), data-turbo-track="reload" will reload on every visit, effectively disabling Turbo. The preferred pattern in that case is to serve the theme as a dedicated stylesheet URL:
<% content_for :l_ui_head do %>
<link rel="stylesheet" href="<%= @tenant.theme_stylesheet_url %>">
<% end %>
Turbo caches and reuses stylesheet responses by URL, so this approach is both Turbo-friendly and avoids inline style blocks entirely.