
Description
Compose PostHog grid canvases — widget grids (including the user's home canvas) built from reusable component canvases. Use when a task asks to add, fill, move, resize, or remove a widget on a grid or home canvas, to compose a whole canvas of widgets from one ask, to build a reusable widget/component, or when a placement id or grid canvas id is the target. Covers the component store search → configure → fork → build ladder, the component placement contract (size, configSchema), the placement lifecycle (pending/generating/live/failed), the guarded layout patch loop, and reading the canvas's comment threads.
SKILL.md
Composing grid canvases
A grid canvas is a composition, not an app: a grid of placements, each rendering a component canvas (a reusable widget with its own source, build, and placement contract). The user's home canvas is an ordinary grid canvas in their personal channel. Layout is data — publishing or patching one is live immediately, with no build.
Three canvas kinds share one lifecycle:
freeform— a standalone app (thebuilding-canvasesskill owns these).component— a reusable widget. Same source/build pipeline as freeform, plus a placement contract. Visibility rides its channel: personal channel = private, team channel = shared.grid— a layout of placements referencing components. No file source; layout only.
The resolution ladder: configure, fork, build
When a grid placement needs content ("a weather widget here", "a kanban of my tasks"), resolve in this order — placing an existing component beats authoring a duplicate:
- Search the store:
canvas-listwithkind=componentandsearch=<what the widget shows>. A component is placeable when bothcomponent_metaandpublished_build_idare set. If itsconfigSchemacan express the request ("weather for Lisbon" → existing weather component withconfig: {"location": "Lisbon"}), place and configure it — write no code. - Fork when a component is close but its config cannot express the ask: read its source
(
canvas-source-retrieve), create a new component (canvas-createwithkind=component), adapt, publish. Name the difference in the new component's description. - Build new when nothing fits — see "Building a component" below.
New components land in the channel you create them in. Create them in the same channel as the grid they serve unless the user asks to share them more widely.
Building a component
A component is authored exactly like a freeform canvas — load building-react-quill-canvases (or
building-html-canvases) plus querying-canvas-data and validating-and-publishing-canvases —
with three additions.
Start from the complete, buildable project in references/component-example.md; its envelope, placement contract, capability declarations, and defensive ph.state access are the parts that break when improvised.
- Create with
kind=componentand adescriptionwritten for store search: say what the widget shows and what its config controls. Future placements are found by this text. - Declare the placement contract in the project's top-level
componentkey:{ "component": { "size": { "defaultW": 2, "defaultH": 1, "minW": 1, "minH": 1, "maxW": 4 }, "configSchema": { "type": "object", "properties": { "location": { "type": "string", "description": "City to show weather for" } } } } }
Size is in grid units (widths 1–12, heights 1–40);minW <= defaultW <= maxW. The range is advisory: users may resize a placement to any size, so it informs defaults and warnings, never rejections. The config schema vocabulary is an allowlist —type,title,description,default,properties,required,additionalProperties,items,enum,const,minimum,maximum,minLength,maxLength,minItems,maxItems,format. No$ref, nopattern— validation rejects them. - Design responsively. Fill 100% of the box's width and height, and adapt the layout to any
size the user drags: a 2×1 placement is a glanceable tile; a 6×4 is a full app surface. Render
usefully at
minW×minH, and treatconfigas the only per-placement input.
Publish and wait for the build like any canvas — a component with no ready build cannot go live on a grid.
Composing a whole canvas
A whole-canvas ask ("a home canvas that summarizes my work in progress") usually means several widgets, not one. Plan the full set first — one placement per concern — then resolve each with the ladder above. Lay them out together: no overlaps, sizes matched to what each widget shows, the grid filled deliberately rather than tiles scattered in a corner. Batch the layout writes (one publish for an initial layout, surgical patches after) instead of one write per widget, and finish with every placement live or failed — never generating.
Canvas comments
Users leave feedback as comment threads on the canvas, anchored to its conversation task.
List them with the task comment tools (tasks-comments-list, tasks-comments-retrieve) on your task before and after changing the canvas, and address the open ones — a comment naming a broken widget is your brief for fixing it.
Editing a grid
The loop is read → patch, guarded exactly as validating-and-publishing-canvases describes for
source publishes — with canvas-layout-get in place of canvas-source-retrieve, and
canvas-layout-patch (surgical ops, guard required) or canvas-layout-publish (complete
document, for an initial layout or full restructure) as the write. On a 409, re-read the layout,
re-apply your change, and patch again.
Operations:
add_placement— a new box:{id, status, x, y, w, h, ...}. Placements must not overlap or extend pastgrid.columns.update_placement— mergechangesinto the placement withid. Filling a drawn box is{"op": "update_placement", "id": "p1", "changes": {"status": "live", "component": "<component canvas id>", "config": {...}}}.remove_placement,set_grid.
The placement lifecycle
A placement's status tells the renderer what to show:
pending— the user drew a box but hasn't described it (or the prompt awaits dispatch).generating— an agent task is filling it;generationTaskIdlinks the task andpromptrecords the ask. Set this when you start working on a placement from a task.live— renders itscomponentatversion("latest"by default; a pinned version id is allowed). Requires the component to be published and visible to the acting user.failed— generation failed; keep thepromptso the user can retry or re-describe.
When a task asks you to fill a placement, its prompt and the box's size are your brief: honor the
drawn w×h and keep the placement's prompt
intact for provenance.
Validation you will hit
Layout publishes validate atomically; every error names its placement. The common ones:
component_not_found— the id is wrong, deleted, not a component, or not visible to the acting user (a component in someone else's personal channel is not placeable).component_not_published— the component has never published a placement contract.placement_config_invalid—configdoes not match the component'sconfigSchema.placement_size_out_of_contract— a warning, not an error: the box'sw/his outside the component's suggested range. The publish still succeeds; the component must render responsively.placements_overlap/invalid_placement— geometry; fix coordinates rather than removing the other widget.
End your reply by linking the grid canvas with the url field the canvas tools return — never
construct a canvas URL yourself.
More skills from the posthog repository
View all 78 skillsanalyzing-expensive-users
analyze expensive users in AI observability
Aug 13AnalyticsCost OptimizationObservabilityPostHogauditing-endpoints
audit PostHog project endpoints
Jun 8AnalyticsAuditPostHogauditing-warehouse-source-health
audit PostHog data warehouse source health
Jun 18AuditData WarehouseObservabilityPostHogauditing-warehouse-view-health
audit PostHog materialized view health
Jun 18AuditData WarehousePerformancePostHogauthoring-data-quality-checks
author data quality checks for warehouse tables
Aug 19AnalyticsData EngineeringData Qualitydbtauthoring-error-tracking-alerts
author PostHog error tracking alerts
Aug 13AlertingDebuggingObservabilityPostHog
More from PostHog
View publisherauthoring-log-alerts
author log alerts in PostHog
posthog
Aug 13AnalyticsMonitoringObservabilityOperations +1building-canvases
create and edit PostHog canvases
posthog
Aug 19AutomationDesignPostHogPrototypingbuilding-html-canvases
author HTML and CSS PostHog canvases
posthog
Aug 6CSSDesignGraphicsHTML +1building-react-quill-canvases
build React and Quill canvases
posthog
Aug 19DesignFrontendReactUI Componentsbuilding-workflows
build and edit PostHog workflows
posthog
Aug 10AutomationMCPPostHogWorkflow Automationcheck-posthog-loading
inspect PostHog SDK loading across URLs
posthog
May 7AnalyticsDebuggingFrontendObservability +1