Skip to content

SE-62 Server-render top-level content on /options/ API reference pages - #7469

Open
taktran wants to merge 4 commits into
latestfrom
se-62/server-render-options-api-reference
Open

SE-62 Server-render top-level content on /options/ API reference pages#7469
taktran wants to merge 4 commits into
latestfrom
se-62/server-render-options-api-reference

Conversation

@taktran

@taktran taktran commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

Closes the SEO/GEO discovery gap on the ~75 /charts/options/ API reference pages (SE-62).

Today these pages render the entire property reference client-side (<ApiReferencePage client:only="react"> fetching a 3.5MB resolved-interfaces.json). The served HTML has no <h1> and no property content — the reference only exists inside a <script> block that JS turns into the page. Googlebot runs JS so pages eventually index, but the first-pass crawl reads an empty page and most AI assistant crawlers don't run JS at all, so the API reference is invisible to them.

Approach

Astro renders slot="fallback" content of a client:only island into the served HTML and swaps it for the React app on hydration. This PR uses that to inject real, crawlable content without touching the React path:

  • New OptionsReferenceFallback.astro — a server-only component that reads the reference via the existing getInterfacesReference() and emits the <h1>, interface description, and a flat list of top-level properties (name, type, default value, description), reusing the existing framework-agnostic helpers (processMembers, normalizeType, parseJsDocs, cleanupName).
  • Wired into options.astro and options/[...memberName]/[type].astro as slot="fallback" on the existing island.

Deep nested type signatures / child properties stay client-rendered (as guided on the ticket) — this keeps the added HTML small and honours the 2MB target from SE-53.

Why not full SSR of the React island

Astro serialises island props into the HTML for hydration; passing the 3.5MB reference (or the closure hydration would need) blows the 2MB budget, and partial data causes React hydration mismatches. The fallback slot sidesteps both, and keeps a single data source with no duplication of the recursive React logic.

Verification

Verified via a direct Astro render (dev server):

  • /options/ served HTML now contains <h1>AgChartOptions</h1> + 90 top-level property rows as real text.
  • /options/axes/radius-number/ renders the correct variant H1 axes.key[type='radius-number'] + 36 rows.
  • The fallback is a direct child of the <astro-island> → cleanly replaced by React on hydration (no duplicate content); the client data file serves 200, so the interactive view renders as before.
  • Added content is ~37KB on the largest page — well under SE-53's 2MB target.
  • nx format ✅ · nx lint ag-charts-website ✅ (0 errors) · no render/hydration warnings.

Notes / follow-ups

  • nx build / e2e were not run here — this checkout has a pre-existing, unrelated failure (ag-charts-generate-example-files can't resolve _ag-charts-test). Please run e2e in a clean environment before merge.
  • Descriptions render as plain text in the fallback (no server-side markdown lib exists; react-markdown is React-only). Fine for crawlers and keeps the zero-dependency rule; the hydrated React view still renders full markdown.
  • SE-62 is currently marked de-scoped on JIRA for "high implementation complexity" — this turned out low-complexity; worth reviving the ticket.

The property reference under /charts/options/ was rendered entirely
client-side (client:only React fetching resolved-interfaces.json), so
the served HTML had no H1 and no property content. Non-JS crawlers,
including most AI assistants, saw an empty page.

Add a server-rendered fallback (Astro slot="fallback") that emits the
H1, interface description, and a flat list of top-level properties
(name, type, default, description) from the same generated reference,
reusing the existing framework-agnostic helpers. Nested children and
deep type signatures stay client-rendered, keeping the added HTML small
(~37KB on the largest page) per SE-53. Astro replaces the fallback with
the interactive React island on hydration, so behaviour is unchanged.
@github-actions

Copy link
Copy Markdown
Contributor

✅ Codex review complete; 1 issue found (P0: 0 | P1: 0 | P2: 1 | P3: 0)

View full review

SE-62 Server-render top-level content on /options/ API reference pages

PR: #7469
Author: taktran | Base: latest ← Head: se-62/server-render-options-api-reference
Diff: 3 files changed, +146 -2

Summary

Adds server-rendered, top-level options reference content as a fallback for crawlers and passes it into the interactive API reference pages.

Findings

P0: 0 | P1: 0 | P2: 1 | P3: 0

1 inline comments posted.

Verdict

Assessment: correct
Confidence: 0.84

The fallback is implemented safely and integrated into both affected pages; the only identified issue is malformed definition-list semantics for undocumented members.

Required Actions: None - ready to merge

@github-actions

Copy link
Copy Markdown
Contributor

Live-test this PR in Plunker

Paste these two <script> tags into a Plunker (or any vanilla-JS host) to load the UMD bundles built from this PR:

<script src="https://ag-grid.github.io/ag-charts/pr-7469/ag-charts-community.min.js"></script>
<script src="https://ag-grid.github.io/ag-charts/pr-7469/ag-charts-enterprise.min.js"></script>

Bundles are removed automatically when the PR is closed. Updated on every push.

taktran added 3 commits July 21, 2026 11:45
The server-rendered fallback rendered as a bare full-width block while the
hydrated ApiReferencePage lays out inside a centred layout-grid with a left-nav
column, so the body jumped horizontally (and, on mobile, vertically) on
hydration.

Mirror the hydrated two-column geometry in the fallback: wrap it in layout-grid,
reserve the left-nav width with an empty placeholder column, and offset the
content column using the same width tokens and breakpoints as objectViewOuter /
referenceOuter. Also reserve the mobile search-box height so content does not
drop when the nav appears. Verified zero shift across mobile, medium and large
viewports.
Undocumented members produced a definition-list group with a <dt> but no <dd>,
which is invalid dl semantics for assistive tech. Always emit the <dd> and drop
its top margin when empty so undocumented rows gain no visual gap.

Addresses Codex P2 review comment.
Rename OptionsReferenceFallback -> ApiReferenceFallback (it is generic over
rootInterface) and wire it into themes-api.astro and the overrides nested page,
so the Themes API reference gets the same crawlable server-rendered top-level
content and layout-shift-safe fallback as /options/.

Verified: /themes-api/ renders AgChartTheme with its top-level members and zero
fallback-to-React shift; /options/ pages unchanged after the rename.

@alantreadway alantreadway left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@taktran

taktran commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

Still needs more testing before we merge this

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.

2 participants