Collaborative infinite-canvas boards for PhoenixKit.
Admins open Boards in the sidebar, create a board, and open it — an
infinite Fresco canvas with the
Etcher drawing layer (shapes, text,
images). Multiple people on the same board see each other's edits, cursors,
and presence in real time. Each board is one row in phoenix_kit_boards
(its Fresco.Canvas document lives in the data jsonb column).
How it works
Zero JS setup. PhoenixKit core already loads
fresco.js+etcher.jsand their hooks (the media annotation feature), so<Fresco.canvas>+<Etcher.layer>work in this module's pages out of the box. This module's own collaboration hooks are delivered by the board page itself, as LiveView runtime hooks — seePhoenixKitBoards.Web.RuntimeHooks. Nothing is asked of the host beyond depending on this module: no compiler entry, no script tag, noapp.jsimport.js_sources/0is still declared, so a host running core's:phoenix_kit_js_sourcescompiler keeps getting the bundle that way and LiveView prefers it. It is no longer load-bearing — which it silently was. A host that bundles dependency JS its own way got no hooks and no error: the board rendered and local edits saved, so the failure looked like "collaboration is broken" rather than "the JS never loaded".Collaboration rides the etcher document: each edit re-emits the full annotation list (
etcher:annotations-changed); the LiveView persists it, broadcasts over PubSub, and peers apply the delta — no canvas remount.Presence + cursors ride plain PubSub on the board's topic.
Installation
# host mix.exs
{:phoenix_kit_boards, "~> 0.4"}Then mix deps.get and mix phoenix_kit.update (creates the
phoenix_kit_boards table). Enable it on the admin Modules page.
Summary
Functions
Tailwind scans this app's templates for classes used by the board UI.
The collaboration + cursors hook bundle. Core's :phoenix_kit_js_sources
compiler concatenates this into the host's phoenix_kit_modules.js (loaded
before app.js) and folds window.PhoenixKitBoardsHooks into
window.PhoenixKitHooks.
The phoenix_kit_boards table coordinator (run by mix phoenix_kit.update).
Multi-page routing (list + individual board) — see PhoenixKitBoards.Routes.
Functions
Tailwind scans this app's templates for classes used by the board UI.
The collaboration + cursors hook bundle. Core's :phoenix_kit_js_sources
compiler concatenates this into the host's phoenix_kit_modules.js (loaded
before app.js) and folds window.PhoenixKitBoardsHooks into
window.PhoenixKitHooks.
A fast path, not a requirement. Hosts that don't run that compiler get the
same hooks from PhoenixKitBoards.Web.RuntimeHooks, which the board page
emits itself; LiveView checks the host's own registration first, so where
both exist this one wins and there is never a second copy.
The phoenix_kit_boards table coordinator (run by mix phoenix_kit.update).
Multi-page routing (list + individual board) — see PhoenixKitBoards.Routes.