
Canvas 1.2 and the composition improvements I've been waiting for
Canvas 1.2 shipped with nested component composition and conditional rendering. What actually changed, and what I'm still watching.
I was waiting for this release. Canvas 1.0 was good enough to use, but it had a gap that showed up immediately: you could not nest composition contexts. A featured-article component that contained a grid that contained cards worked, but if you wanted the cards to know they were inside a featured article, or if you wanted the grid to adjust based on that context, you were back to custom code.
Canvas 1.2 closes that gap. Components can now declare context dependencies. A card can say “I work best if I am inside a grid context.” A grid can provide context to its children. And crucially — this is the thing I was actually waiting for — a component can render conditionally based on that context.
It sounds like jargon. The impact is that composition becomes genuinely expressive.
What the old way looked like
Let me use a concrete example. A university’s featured article section has a headline, an image, a deck of article cards. Each card needs different styling depending on whether it is the featured card or a supporting card. In Canvas 1.0, you had two options: use separate components for featured and supporting cards, or build the styles to handle both cases with CSS.
Both worked, but neither was clean. Separate components meant duplicated markup. CSS handling both cases meant the card component got complex. You ended up doing work that felt like it should have been the grid’s job.
How 1.2 changes it
name: Featured Article Gridprovides: context: featured-position: type: integer description: Index of the featured article (0 = featured, rest = supporting)The grid component now declares that it provides context. A card component can declare that it needs it:
name: Cardrequires: context: featured-position: {} layout: {}props: schema: type: object properties: title: { type: string } excerpt: { type: string }In the card’s Twig template, it can now access that context:
<article class="card" data-position="{{ context.featured_position }}"> {% if context.featured_position == 0 %} <div class="card--featured"> {# Featured styling #} </div> {% else %} <div class="card--supporting"> {# Supporting styling #} </div> {% endif %}</article>The CSS can target [data-position="0"] for featured, [data-position="1"] for supporting. The component still has one schema. The grid provides context. The composition is explicit.
What this actually solves
This pattern scales. A footer component can declare context: “I provide a theme context.” Every component inside that footer can respond to it. A dark-mode footer causes all its children to render with dark-mode styles.
A multisite platform can declare site-specific context: “This canvas defines institution=medical-school.” A component can render differently based on institution. No conditional logic in the component itself. The context is provided by the composition layer.
The accessibility here is elegant. A component does not have to guess its context. It receives it. The composition layer is responsible for providing it correctly. If a card requires featured-position and the grid does not provide it, Canvas warns you at composition time, not at render time.
What I am still figuring out
The one thing I have not fully solved is validation. If a card requires context and is placed outside a grid that provides it, Canvas warns you. Good. But what happens with multisite platforms where the same card is used in different contexts? Some sites have the context. Others do not.
I think the answer is that the context is optional: a card says “I can use featured-position if it is available, but I have a fallback if it is not.” Canvas supports that. But having worked with multisite platforms, I know the fallback that seems safe becomes the path everyone takes, and then the context never actually gets used.
The other thing I am uncertain about is performance. Context is passed down the tree. A deep nesting of components all checking context at render time could add overhead. I am watching to see what the benchmarks look like at scale.
The last thing is conditional rendering based on data. Right now, context is meta-information — “you are in a featured position.” What about rendering conditionally based on the actual data? “Render this section only if the article has an event date.” That is still custom code.
For now, Canvas 1.2 is doing what it should do: making composition more expressive without requiring code. I am watching what patterns emerge when teams start using context heavily.
What this came from
- ArticleCanvas 1.2 release notes