Skip to content

fix(cli): #1770 pass the page node to getBody for develop SSR pages without a segment - #1775

Open
jstockdi wants to merge 2 commits into
ProjectEvergreen:masterfrom
Battle-Creek-LLC:bug/issue-1770-develop-ssr-page-object
Open

fix(cli): #1770 pass the page node to getBody for develop SSR pages without a segment#1775
jstockdi wants to merge 2 commits into
ProjectEvergreen:masterfrom
Battle-Creek-LLC:bug/issue-1770-develop-ssr-page-object

Conversation

@jstockdi

@jstockdi jstockdi commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Related Issue

Resolves #1770

Documentation

No documentation changes. This aligns greenwood develop with the already documented and already correct greenwood build + greenwood serve behavior for the page argument of getBody.

Summary of Changes

For an SSR page whose route has no dynamic segment, develop was handing getBody(compilation, page, request, params) an empty object, while build + serve handed it the fully populated page node from the graph. So page.title, page.route, page.data etc. were undefined in development and correct in production, with no error in either mode.

In packages/cli/src/plugins/resource/plugin-standard-html.js:

const matchingRouteWithSegment = getMatchingDynamicSsrRoute(this.compilation, pathname) || {};
// ...
page: JSON.stringify(matchingRouteWithSegment ?? matchingRoute),

getMatchingDynamicSsrRoute returns undefined when nothing matches, but the || {} turned that into {}. {} is not nullish, so the ?? never fell through to matchingRoute — which is resolved on the very same request a couple of lines above and is used for the layout further down, so the correct node was available the whole time.

The fix drops the || {} so the ?? can do its job, and switches the two unguarded property reads on that variable to optional chaining so they behave exactly as they did when it was defaulted to {}:

  • matchingRoute.isSSR || matchingRouteWithSegment?.isSSR
  • new URL(pageHref ?? matchingRouteWithSegment?.pageHref)

The other two reads (matchingRouteWithSegment && matchingRouteWithSegment.segment for params) were already guarded and are untouched.

getLayout was not affected — it is dispatched separately from lib/layout-utils.js with the real node — and layout behavior is unchanged here.

Tests

Folded into the existing develop.ssr case rather than adding a new directory:

  • new fixture packages/cli/test/cases/develop.ssr/src/pages/page-object.js, an SSR page with getBody + getFrontmatter and no dynamic segment, which renders page.id, page.route and page.title
  • new describe block asserting those rendered values match the corresponding node in .greenwood/graph.json

packages/cli/test/cases/develop.ssr:

passing failing
before the fix 33 1 (expected 'undefined' to equal 'page-object')
after the fix 34 0

Also re-ran, all green: develop.dynamic-routing, develop.dynamic-routing-static-paths, develop.typescript.ssr, serve.dynamic-routing, serve.dynamic-routing-static-paths (33 passing), and build.default.ssr-prerender, build.default.ssr-static-export, serve.default.ssr, serve.dynamic-routing (144 passing).

Note

#1766's fix also lands in packages/cli/src/plugins/resource/plugin-standard-html.js, around the fs.readFile a dozen lines below this hunk. The two changes are disjoint and should merge cleanly in either order.

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.

develop passes an empty page object to getBody for SSR pages without a dynamic segment

1 participant