Skip to content

Comments

Add theme-related head tags when available#4010

Draft
backspace wants to merge 32 commits intomainfrom
head-format-theme-cs-9828
Draft

Add theme-related head tags when available#4010
backspace wants to merge 32 commits intomainfrom
head-format-theme-cs-9828

Conversation

@backspace
Copy link
Contributor

@backspace backspace commented Feb 17, 2026

You can see the new test fail here before the implementation commit.

…d format

Add test verifying that the default head template emits <link rel="icon">
and <link rel="apple-touch-icon"> tags when a card has a BrandGuide linked
as cardInfo.theme with a socialMediaProfileIcon.

CS-9828

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@backspace backspace self-assigned this Feb 17, 2026
@backspace backspace added the enhancement New feature or request label Feb 17, 2026
backspace and others added 2 commits February 17, 2026 12:30
…t head format

When a card has a BrandGuide (or other Theme subclass) linked as
cardInfo.theme, the default head template now emits <link rel="icon">
and <link rel="apple-touch-icon"> tags using the theme's cardThumbnailURL,
which for BrandGuide falls back to markUsage.socialMediaProfileIcon.

CS-9828

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Feb 17, 2026

Host Test Results

    1 files  ±0      1 suites  ±0   1h 38m 46s ⏱️ - 2m 32s
1 856 tests ±0  1 842 ✅ ±0  14 💤 ±0  0 ❌ ±0 
1 871 runs  ±0  1 857 ✅ ±0  14 💤 ±0  0 ❌ ±0 

Results for commit a7b3bc9. ± Comparison against base commit 371901a.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

Preview deployments

backspace and others added 17 commits February 18, 2026 12:31
When a `contains` or `containsMany` field returns a FieldDef instance,
the parent's store was not propagated to it. This meant that nested
`linksTo` fields (e.g., `cardInfo.theme`) couldn't properly track their
lazy loads — `getStore()` returned a throwaway FallbackCardStore instead
of the real store. The two-pass render's `waitForLinkedData` never saw
these loads, so linked data was never resolved.

Fix: propagate the store from parent to child in Contains/ContainsMany
getters, matching the existing `propagateRealmContext` pattern.

Also clean up debug logging in the theme icon test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Temporary debug output to understand why cardInfo.theme doesn't resolve
during head prerendering. The debug-card-info meta tag will show whether
theme is undefined, null, or has a URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…as default

- Remove debug diagnostic getter and meta tag from head.gts
- Remove hardcoded staging URLs from head template fallback
- Head template now only emits favicon/apple-touch-icon when themeIcon exists
- Uncomment static favicon and apple-touch-icon in index.html (outside markers)
- Add tests for all icon scenarios: static defaults, no-theme head injection,
  non-public realm, and theme icon injection
- Add DB diagnostic in theme test to debug prerender resolution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rder

Include linked card URLs (from linksTo relationships) in the deps list
computed by render/meta.ts. This ensures backward invalidation re-indexes
a card when its linked cards are created or updated — critical for
linksTo fields like cardInfo.theme that may not resolve during initial
indexing if the linked card hasn't been indexed yet.

Also rename test-theme.json to a-test-theme.json so it sorts
alphabetically before card-with-theme.json. The from-scratch indexer
processes .json files in alphabetical order without backward
invalidation, so the theme card must be indexed first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
From-scratch indexing writes to boxel_index_working and only commits
to boxel_index when the batch completes. This means cards within the
same batch can't resolve linksTo references to each other during
prerender. Create card-with-theme via API after the realm is up,
triggering incremental indexing when the theme card is already in
the production table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The prerender captures formats in sequence: meta → head → atom → etc.
During renderMeta, store.loaded() is awaited and data-prerender-status
is set to "ready". When the head format then renders, captureResult
finds the status already "ready" and captures immediately — before any
newly triggered async loads (like cardInfo.theme) can complete.

Fix by having #touchIsUsedFields also touch linksTo/linksToMany fields
nested within contains FieldDefs. This ensures their async loads are
tracked by store.loaded() and resolved before the model is marked as
"ready", so the head template captures the fully resolved theme icon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a card has nested relationships like "cardInfo.theme" but no
corresponding attribute entry for "cardInfo", the _updateFromSerialized
function never called Contains.deserialize, silently losing the nested
linksTo reference. This caused cardInfo.theme to always be null during
prerender, preventing the head template from rendering theme icons.

The fix identifies contains fields that have nested relationships but
no attribute value and ensures they are included in the deserialization
iteration. This creates the proper NotLoadedValue for nested linksTo
fields, enabling lazy loading during prerender.

Also removes diagnostic output from the theme head test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Temporary diagnostic output to understand why head_html is empty string
during prerender. Also checks the theme card itself in the DB.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… resource column

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ine_doc structure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This tests whether the issue is in the nestedRelFieldStubs fix by using
the regular Contains deserialization path (attributes.cardInfo present).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove nestedRelFieldStubs from _updateFromSerialized in card-api.gts
  (CI confirmed it doesn't work; real cards always have contains fields
  in attributes, making this code path unnecessary)
- Remove diagnostic console.log from render.ts model hook and
  #touchNestedLinksToFields (keep method logic, remove logging)
- Remove diagnostic DB queries from theme test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
backspace and others added 8 commits February 20, 2026 07:49
Replace the overly aggressive #touchNestedLinksToFields approach (which
loaded ALL nested linksTo fields, including hidden ones that shouldn't
appear in deps) with #resetModelForFormatTransition.

When the prerender pipeline transitions between formats (isolated → head
→ fitted → etc.), the model status is already "ready" from the previous
format. If the new format template triggers lazy loads (e.g., the head
template accessing cardInfo.theme.cardThumbnailURL), captureResult would
capture before those loads resolve.

The new approach resets the model status to "loading" before each format
transition, then re-settles via afterRender + store.loaded(). This way
captureResult waits for any lazy loads triggered by the new template
without pre-loading hidden relationships.

Also removes the manually-added relationship deps from render/meta.ts
(now handled by the new dependency resolver from main).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…nsitions

#resetModelForFormatTransition was being called for ALL render.* child
route transitions, including render.meta. The render.meta model hook
explicitly awaits readyPromise, so resetting it to a new unfulfilled
deferred could cause hangs due to Ember run loop timing issues.

Only render.html transitions render card templates that might trigger
new lazy loads (e.g., head format accessing cardInfo.theme). Other child
routes (render.meta, render.icon, render.error) don't need the reset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…uild

The #resetModelForFormatTransition() method was resetting model status to
"loading" on every render.html transition, which interfered with the
prerendering multi-format capture flow (isolated → meta → head → etc.)
on reused pooled pages, causing timeouts in prerendering-test.ts.

Instead, pre-load cardInfo.theme during initial model building so the
data is already available when the head template renders favicon and
apple-touch-icon tags. This avoids the need to reset model state between
format transitions entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…moval

Testing whether the pre-load is the cause of Host Tests (4, 16) failures.
The prerendering-test fix (removal of resetModelForFormatTransition) stays.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When prerendering captures multiple formats sequentially (isolated → head →
fitted → etc.), the model is already "ready" after the first format settles.
Subsequent format templates may access fields not touched by the first format
(e.g., the head template reads cardInfo.theme), triggering lazy linksTo loads.
Without resetting, captureResult sees "ready" immediately and captures before
those loads complete — producing head HTML missing theme-based link tags.

The previous version of this method broke page reuse: during reuse the
__renderModel briefly points to the *previous* card's model while the new
model builds. Resetting that stale model left its status stuck at "loading",
blocking the page pool indefinitely.

The fix adds a nonce guard: only reset when __renderModel.nonce matches the
current renderBaseParams nonce, ensuring we never touch a stale model.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant