Remove index card to avoid flash of empty cards-grid in host mode#3994
Remove index card to avoid flash of empty cards-grid in host mode#3994
Conversation
Host Test Results 1 files ± 0 1 suites ±0 3h 8m 48s ⏱️ + 1h 34m 16s Results for commit 780aadf. ± Comparison against base commit fcf29c5. This pull request removes 3 and adds 110 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 780aadfd9b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const updated = { | ||
| data: { | ||
| type: 'card', | ||
| meta: { | ||
| adoptsFrom: { |
There was a problem hiding this comment.
Preserve index card metadata during migration
This migration rebuilds each matched index.json from a fixed updated object and drops data.attributes entirely, so running in apply mode erases any existing index-card metadata (for example cardInfo.name, cardInfo.summary, or thumbnail values) instead of just removing the obsolete relationship fields. Because CardsGrid still inherits these fields from CardDef, this is destructive data loss for realms that customized their home card metadata.
Useful? React with 👍 / 👎.
|
|
||
| // Only process files that adopt from IndexCard | ||
| const adoptsFrom = data?.data?.meta?.adoptsFrom; | ||
| if (!adoptsFrom || adoptsFrom.name !== 'IndexCard') { |
There was a problem hiding this comment.
Limit migration to the base IndexCard module
The migration selector only checks adoptsFrom.name === 'IndexCard' and ignores the module, so any realm-specific card type also named IndexCard will be rewritten to https://cardstack.com/base/cards-grid and have its original shape discarded. For a script intended to scan staging/production trees, this can incorrectly rewrite unrelated custom cards; the predicate should also verify the expected base module before applying changes.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR removes the IndexCard wrapper component to eliminate a flash of empty cards-grid during prerendering. The IndexCard previously conditionally rendered different home cards (interactHome, hostHome, or cardsGrid) based on mode/submode context, but this context is not available during prerendering, causing the template to always fall through to cardsGrid. The PR simplifies the architecture by making index cards directly adopt from CardsGrid.
Changes:
- Removed IndexCard component and replaced it with a backward-compatible export alias to CardsGrid
- Updated realm creation and setup scripts to seed index.json as CardsGrid instances
- Added migration script to convert existing IndexCard instances to CardsGrid in production environments
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| scripts/migrate-index-to-cards-grid.js | New migration script to convert index.json files from IndexCard to CardsGrid adoption |
| packages/realm-server/server.ts | Updated realm creation to generate index.json directly as CardsGrid, removing cards-grid.json creation |
| packages/realm-server/scripts/setup-submission-realm.sh | Updated submission realm setup to create index.json as CardsGrid |
| packages/realm-server/tests/server-endpoints/maintenance-endpoints-test.ts | Updated test expectations for file/instance counts after removing cards-grid.json |
| packages/host/tests/acceptance/index-home-test.gts | Removed test file as interactHome/hostHome functionality no longer exists |
| packages/experiments-realm/index.json | Migrated from IndexCard to CardsGrid adoption |
| packages/base/index.json | Migrated from IndexCard to CardsGrid adoption with relative module path |
| packages/base/index.gts | Replaced IndexCard implementation with backward-compatible export alias |
| packages/base/cards-grid.json | Removed redundant cards-grid.json file |
| packages/base/cards-grid.gts | Simplified query filters to no longer exclude IndexCard |
| packages/experiments-realm/cards-grid.json | Removed redundant cards-grid.json file |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Replace with CardsGrid adoption, strip relationships and attributes | ||
| const updated = { | ||
| data: { | ||
| type: 'card', | ||
| meta: { | ||
| adoptsFrom: { | ||
| module: 'https://cardstack.com/base/cards-grid', |
There was a problem hiding this comment.
The migration script always uses the absolute module URL 'https://cardstack.com/base/cards-grid', but the manually migrated packages/base/index.json uses the relative path './cards-grid'. This inconsistency means that if this migration script is run on the base realm's index.json, it would change the relative path to an absolute URL. Consider making the script preserve relative paths when the original adoptsFrom uses a relative path (e.g., './index'), or ensure that all migrated files use the same convention (all absolute or all relative based on their context).
| // Replace with CardsGrid adoption, strip relationships and attributes | |
| const updated = { | |
| data: { | |
| type: 'card', | |
| meta: { | |
| adoptsFrom: { | |
| module: 'https://cardstack.com/base/cards-grid', | |
| // Determine appropriate module path for CardsGrid: | |
| // - preserve relative paths (e.g. "./index" -> "./cards-grid") | |
| // - otherwise use the absolute base URL | |
| const originalModule = adoptsFrom.module; | |
| const cardsGridModule = | |
| typeof originalModule === 'string' && originalModule.startsWith('.') | |
| ? './cards-grid' | |
| : 'https://cardstack.com/base/cards-grid'; | |
| // Replace with CardsGrid adoption, strip relationships and attributes | |
| const updated = { | |
| data: { | |
| type: 'card', | |
| meta: { | |
| adoptsFrom: { | |
| module: cardsGridModule, |
There was a problem hiding this comment.
I think this only applies to the base index card which will never have this script executed on it, IIUC
There was a problem hiding this comment.
You're right, this script will never be executed on base realm.
backspace
left a comment
There was a problem hiding this comment.
I confess to not being totally sure what the right way through this normalisation is as we move toward host mode routing
| // Replace with CardsGrid adoption, strip relationships and attributes | ||
| const updated = { | ||
| data: { | ||
| type: 'card', | ||
| meta: { | ||
| adoptsFrom: { | ||
| module: 'https://cardstack.com/base/cards-grid', |
There was a problem hiding this comment.
I think this only applies to the base index card which will never have this script executed on it, IIUC
The IndexCard acts as a wrapper that conditionally renders interactHome, hostHome, or cardsGrid based on the current mode/submode context. During prerendering, the mode/submode context is not available, so interactHome and hostHome are never rendered — the template always falls through to the cardsGrid fallback. This causes a flash of empty cards-grid content before the app hydrates and resolves the correct home card. With the upcoming routing MVP, this indirection layer becomes unnecessary. Removing IndexCard simplifies the index card to always be a CardsGrid directly, eliminating the flash and the conditional rendering complexity.