Advanced

Slots

HEEx markup passed into React as children

  • inner_block
  • children

Key concepts

The default slot passed to <.react> becomes children in React. It is ordinary HEEx — a .button with a phx-click, in this case — rendered by the LiveView and handed to React as markup, not as data.

Slots.tsx
import React from "react";

// `children` here is not React markup — it's HEEx, rendered by the
// LiveView and handed over as a slot. React treats it like any other
// child: it doesn't know or care where it came from.
export function Slots({
  count,
  children,
}: {
  count: number;
  children: React.ReactNode;
}) {
  return (
    <div className="flex items-center gap-4">
      <span className="text-xl">{count}</span>
      {children}
    </div>
  );
}

How it works

The button inside the slot is not wired through pushEvent at all — it's a plain phx-click that Phoenix handles the same way it would outside a React tree. React only renders children; it has no idea the markup came from HEEx.

This is the tool for mixing an existing LiveView component — a modal, a table row, anything already built in HEEx — into a page that's otherwise composed with React, without rewriting it.