# `PhoenixKitWeb.Components.LayoutWrapper`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v2.2.0/lib/phoenix_kit_web/components/layout_wrapper.ex#L1)

Dynamic layout wrapper component for Phoenix v1.7- and v1.8+ compatibility.

This component automatically detects the Phoenix version and layout configuration
to provide seamless integration with parent applications while maintaining
backward compatibility.

## Usage

Replace direct layout calls with the wrapper:

    <%!-- OLD (Phoenix v1.7-) --%>
    <%!-- Templates relied on router-level layout config --%>

    <%!-- NEW (Phoenix v1.8+) --%>
    <PhoenixKitWeb.Components.LayoutWrapper.app_layout flash={@flash}>
      <%!-- content --%>
    </PhoenixKitWeb.Components.LayoutWrapper.app_layout>

## Configuration

Configure parent layout in config.exs:

    config :phoenix_kit,
      layout: {MyAppWeb.Layouts, :app}

# `app_layout`

Renders content with the appropriate layout based on configuration and Phoenix version.

Automatically handles:
- Phoenix v1.8+ function component layouts
- Phoenix v1.7- legacy layout configuration
- Fallback to PhoenixKit layouts when no parent configured
- Parent layout compatibility with PhoenixKit assigns

## Attributes

- `flash` - Flash messages (required)
- `phoenix_kit_current_scope` - Current authentication scope (optional)
- `phoenix_kit_current_user` - Current user (optional, for backwards compatibility)

## Inner Block

- `inner_block` - Content to render within the layout

## Attributes

* `flash` (`:map`) - Defaults to `%{}`.
* `socket` (`:any`) - Defaults to `nil`.
* `phoenix_kit_current_scope` (`:any`) - Defaults to `nil`.
* `phoenix_kit_current_user` (`:any`) - Defaults to `nil`.
* `page_title` (`:string`) - Defaults to `nil`.
* `page_subtitle` (`:string`) - Defaults to `nil`.
* `page_section` (`:string`) - Optional breadcrumb segment rendered between "Admin Panel" and `page_title` (e.g. "Users" on a user detail page). Desktop only — collapses along with the rest of the breadcrumb prefix on mobile. Defaults to `nil`.
* `page_section_path` (`:string`) - Prefixed path (via `PhoenixKit.Utils.Routes.path/1`) the `page_section` crumb links to. Renders as plain text when omitted. Defaults to `nil`.
* `page_action` (`:map`) - Optional compact action button rendered right after the breadcrumb title: `%{icon: "hero-plus", label: "New template", navigate: path}`. Lets a page keep its primary create action without spending an in-content header row. `label` becomes the tooltip/aria-label; `icon` defaults to hero-plus. Navigation only — for a `phx-click` action (or anything needing `phx-target`), use the `:action` slot instead. ⚠️ Plugin LiveViews rendered through the admin layout can only use this map: the layout threads it as an assign, and a slot cannot travel that way. Defaults to `nil`.
* `current_path` (`:string`) - Defaults to `nil`.
* `inner_content` (`:string`) - Defaults to `nil`.
* `project_title` (`:string`) - Defaults to `nil`.
* `current_locale` (`:string`) - Defaults to `nil`.
* `from_layout` (`:boolean`) - Defaults to `false`.
* `pk_pending_invitations` (`:list`) - Defaults to `[]`.
* `module_assigns` (`:map`) - Module-supplied host-consumable assigns. Each key in this map is merged into the assigns set passed to the parent layout (`Layouts.app`), so a host's custom layout can read e.g. `assigns[:phoenix_kit_publishing_translations]` from publishing, or any other module-defined key. Plain `conn.assigns` don't reach a function-component layout — only declared attrs do — so this single map attribute is how modules thread arbitrary host-consumable data through the boundary without core having to declare each one explicitly. Defaults to `%{}`.
## Slots

* `action` - The same compact action button, for pages whose primary action is not a
  navigation — a `phx-click`, a `JS` command, anything needing `phx-target`.
  The map attribute cannot express those and cannot address a LiveComponent.

  Takes render priority over the `page_action` attribute. Content is wrapped
  in the same chip shell, and the contract is **one compact control**: a
  multi-action toolbar belongs in the page body, not the breadcrumb bar.

  ⚠️ Only reaches views calling `app_layout/1` directly. Plugin LiveViews
  render through `layouts/admin.html.heex`, which threads `page_action` as an
  assign — slots do not travel through assigns — so those keep the map.

      <:action>
        <button phx-click="new_device" phx-target={@myself} title="Add device">
          <.icon name="hero-plus" class="w-4 h-4" />
        </button>
      </:action>

* `inner_block`

# `auth_layout`

Rendering path for auth pages (login, register, reset, confirm, magic link,
QR handoff, and the invite-only referral screen).

Auth pages **do not** render inside the host's `Layouts.app`. That layout is
where a `mix phx.new` app keeps its logo, framework version and off-site
links, so wrapping sign-in in it put Phoenix Framework branding on the login
page of every kit install — reported by more than one host. Admin already
works this way (`render_admin_with_parent/1` never calls the host's `:app`);
auth was the outlier.

The host's **root** layout still applies, because `PhoenixKitWeb.Integration`
never calls `put_root_layout`. That is where the document shell, assets and
CSRF come from, and it is unaffected.

A host that genuinely wants its own chrome on sign-in opts back in:

    config :phoenix_kit, auth_uses_host_layout: true

⚠️ Two things a host may notice when it does not: anything wired into the
**app** layout rather than root — a cookie-consent banner, analytics, a theme
toggle — stops appearing on auth pages only. Root-level wiring is unaffected.
Stock `phx.new` puts assets and CSRF in root, so conventional hosts see only
the branding disappear, which is the point.

## Attributes

* `flash` (`:map`) (required)
* `phoenix_kit_current_scope` (`:any`) - Defaults to `nil`.
* `page_title` (`:string`) - Defaults to `nil`.
* `current_path` (`:string`) - Defaults to `nil`.
* `pk_pending_invitations` (`:list`) - Defaults to `[]`.
## Slots

* `inner_block` (required)

# `build_locale_url`

# `generate_language_switch_url`

# `get_language_flag`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
