Skip to content

Make prerender more reliable for query fields#4067

Open
habdelra wants to merge 19 commits intomainfrom
cs-10228-prerendering-doesnt-capture-relationships-in-non-isolated
Open

Make prerender more reliable for query fields#4067
habdelra wants to merge 19 commits intomainfrom
cs-10228-prerendering-doesnt-capture-relationships-in-non-isolated

Conversation

@habdelra
Copy link
Contributor

@habdelra habdelra commented Feb 25, 2026

This change set improves prerender reliability for query-backed UIs by closing timing/auth/recovery gaps from card/module hydration through render-settle capture. It ensures query-driven and nested relationship content (for example hero mini-cards) is loaded before prerender is marked ready, ensures fallback federated-search calls execute with the correct auth/realm context, and aligns timeout/retry behavior across prerender layers. It also hardens failure recovery by treating unhandled rejection-style render failures as eviction-worthy so pooled pages recover cleanly. Tests were expanded and split to reproduce delayed-query/nested-load conditions and private/public fallback-search auth paths, validating that captured HTML/search docs now include expected dynamic content.

Here is a prerender of the homepage index.json isolated format from this branch:

Screenshot from 2026-02-25 10-36-27

Here is the isolated html for the homepage index.json, which includes the hero-mini-cards in the captured HTML:

Screenshot from 2026-02-25 10-35-32

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request enhances prerender reliability for query-backed UIs by addressing timing, authentication, and recovery gaps throughout the prerender pipeline. The changes ensure that query-driven and nested relationship content (such as hero mini-cards) is fully loaded before prerender is marked ready, that fallback federated-search calls execute with correct auth/realm context, and that timeout/retry behavior is aligned across all prerender layers.

Changes:

  • Centralized and increased prerender timeout configuration (90s render, 150s request with overhead)
  • Implemented multi-pass render settle logic with load generation tracking to capture nested query-backed relationships
  • Added realm-aware authentication for federated search fallback queries
  • Enhanced eviction logic to detect and recover from unhandled promise rejections
  • Enriched metadata propagation (realmURL, lastModified) from response headers to support query field fallback
  • Improved relationship deserialization to handle both array and relationship object formats

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/realm-server/prerender/prerender-constants.ts New centralized timeout configuration with env var parsing and defaults (90s render, 60s overhead)
packages/realm-server/prerender/utils.ts Updated to use centralized timeout constants
packages/realm-server/prerender/remote-prerenderer.ts Updated to use centralized timeout resolution
packages/realm-server/prerender/manager-app.ts Updated to use centralized timeout resolution
packages/realm-server/prerender/render-runner.ts Added eviction logic for promise rejection errors (status >= 500 with "reject"/"rsvp" in message)
packages/runtime-common/document.ts Enriched document metadata with realmURL and lastModified from response headers
packages/host/app/services/store.ts Added realmURL metadata for source-mode loads, exposed loadGeneration for settle tracking, switched to maybeAuthedFetchForRealms
packages/host/app/services/realm-server.ts Added maybeAuthedFetchForRealms method with realm-specific token selection from localStorage
packages/base/query-field-support.ts Enhanced fallback search triggering to detect unhydrated relationship targets
packages/base/card-api.gts Updated linksTo/linksToMany deserialization to use resourceId from data.id as fallback reference, handle relationship objects in linksToMany
packages/host/app/routes/render.ts Implemented multi-pass settle logic (20 passes max, 2 stable required) with loadGeneration tracking
packages/host/app/routes/module.ts Restructured to wrap all module loading work in single authGuard.race call for consistent auth error handling
packages/host/app/services/render-service.ts Added multi-pass async rendering (3 passes) to allow nested query work to complete
packages/host/app/lib/gc-card-store.ts Exposed loadGeneration getter for render settle tracking
packages/realm-server/tests/prerendering-test.ts Added comprehensive tests for public/private realm query fallback auth, updated templates with hero-mini-card structure, added indexing await
packages/realm-server/tests/helpers/prerender-page-patches.ts Added installSearchRequestObserverPatch for verifying auth headers on federated search requests
packages/realm-server/scripts/start-all.sh Increased WAIT_ON_TIMEOUT from 1200s to 2000s (~33 minutes) to accommodate longer prerender operations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

Preview deployments

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23c5b46a45

ℹ️ 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".

@habdelra habdelra requested a review from a team February 25, 2026 23:59
timeoutMessage?: string;
}

export async function waitForLoadedImage(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was to fix flaky image tests

// links.self is used to tell the consumer of this payload how to get the resource via HTTP.
// data.id is used to tell the consumer how to find the resource in the included bucket.
// Prefer data.id for resourceFrom(), and fall back to links.self when data.id is missing
// (the array-style linksToMany format omits data.id).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you only moved this comment, but it seems like a bug if only linksToMany omits data.id

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that is the case anymore though (i think AI moved the comment to be consistent with the declaration of resourceId), but this comment is actually ancient. probably we can remove this note in the comment.

@github-actions
Copy link

Host Test Results

    1 files  ±0      1 suites  ±0   1h 44m 16s ⏱️ + 10m 26s
1 879 tests ±0  1 864 ✅ ±0  15 💤 ±0  0 ❌ ±0 
1 894 runs  ±0  1 879 ✅ ±0  15 💤 ±0  0 ❌ ±0 

Results for commit e4f5b3a. ± Comparison against base commit 61ceac3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants