Skip to content

Layouts

The overall page chrome — topbar, sidebar, footer, body wrapping. Plutonium ships two shells; you can eject the templates or write a custom ResourceLayout for total control.

Shell

ruby
Plutonium.configure do |config|
  config.shell = :modern     # default — topbar + icon rail
  # config.shell = :classic  # legacy header + sidebar (only when upgrading)
end

:classic is only for upgrade paths

If you're starting fresh, use :modern. :classic exists so apps upgrading from pre-:modern versions can preserve their chrome while migrating.

Eject the chrome for per-portal customization

bash
rails generate pu:eject:shell --dest=admin_portal
rails generate pu:eject:layout

pu:eject:shell copies _resource_header.html.erb and _resource_sidebar.html.erb into the portal's app/views/plutonium/. The eject is independent of shell — you can run it on either.

pu:eject:layout copies layouts/resource.html.erb for layout-level edits.

Custom layout class

For full Phlex-level control over the layout:

ruby
module AdminPortal
  class ResourceLayout < Plutonium::UI::Layout::ResourceLayout
    private

    def body_attributes
      {class: "antialiased bg-[var(--pu-body)]"}
    end

    def render_before_main
      super
      render AnnouncementBanner.new if Announcement.active.any?
    end

    def render_body_scripts
      super
      script(src: "/custom-analytics.js")
    end
  end
end

Layout hooks

HookPosition
render_before_main / _after_mainaround the main content area
render_before_content / _after_contentinside main, around content
render_flashflash messages
render_head, render_title, render_metatags, render_assetshead section
render_body_scriptsend-of-body scripts
render_fontsfont links

Typography

Plutonium uses Lato by default. Override via render_fonts:

ruby
class MyLayout < Plutonium::UI::Layout::ResourceLayout
  def render_fonts
    link(rel: "preconnect", href: "https://fonts.googleapis.com")
    link(href: "https://fonts.googleapis.com/css2?family=Inter&display=swap", rel: "stylesheet")
  end
end

Then configure Tailwind to match:

javascript
// tailwind.config.js
theme: plutoniumTailwindConfig.merge(plutoniumTailwindConfig.theme, {
  fontFamily: {
    body: ['Inter', 'sans-serif'],
    sans: ['Inter', 'sans-serif']
  }
})

See Assets › Tailwind config for the full merge story.

Dark mode

selector strategy — toggle by adding/removing dark on <html>. The bundled color-mode Stimulus controller handles toggling; Plutonium ships a switcher.

javascript
// Manual toggle if needed
document.documentElement.classList.toggle('dark')
  • Assets — Tailwind config, design tokens, .pu-* classes
  • Components — custom components used in layout hooks (AnnouncementBanner, etc.)
  • Pages — page-level hooks (a lighter alternative for per-page chrome)

Released under the MIT License.