From e8390da74cdfdf90cfd162cdb6a345a89b4df412 Mon Sep 17 00:00:00 2001 From: Bret Comnes Date: Sat, 18 Apr 2026 11:31:38 -0700 Subject: [PATCH 1/3] document global.data.js caveats for vars getter and rendering --- README.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/README.md b/README.md index 008f8fb..8ab1043 100644 --- a/README.md +++ b/README.md @@ -1053,6 +1053,38 @@ The returned object is stamped onto every page's vars before rendering, so any p Use `GlobalDataFunction` or `AsyncGlobalDataFunction` to type the function where `T` is the shape of the object you return. +**Caveats:** + +**`page.vars` is a computed getter.** Each access performs a fresh merge of all variable sources. Cache the result when reading multiple properties from the same page: + +```js +// good: one merge per page +const vars = page.vars +const { title, date } = vars + +// avoid: merges on every property access +const title = page.vars.title +const date = page.vars.date +``` + +For large sites with hundreds of pages, caching the result once per page reduces build time noticeably. + +**`page.vars` can throw.** If a page vars module has a syntax error, a missing dependency, or a runtime error, accessing `.vars` will throw. Wrap accesses in `try/catch` when iterating all pages so one broken page does not abort the whole function: + +```js +const posts = pages.filter(p => { + try { + return p.vars.layout === 'article' && p.vars.date + } catch { + return false + } +}) +``` + +**`page.vars.content` is raw source, not rendered HTML.** For markdown pages, `vars.content` is the raw markdown string read from the file. To get rendered HTML, call `page.renderInnerPage({ pages })`. + +**`renderInnerPage()` is available.** `global.data.js` receives fully initialized `PageData` instances, so you can call `renderInnerPage()` here. See [Accessing rendered page content](#accessing-rendered-page-content) for usage and performance guidance. + ### `esbuild.settings.ts` This is an optional file you can create anywhere. From dfd8a1650d665496327e4fb93a400895550c5a2d Mon Sep 17 00:00:00 2001 From: Bret Comnes Date: Sat, 18 Apr 2026 12:02:03 -0700 Subject: [PATCH 2/3] Fix three global.data caveats doc issues - Cache p.vars in try/catch example to avoid double-invoking the getter - Broaden the .vars throw caveat to cover all init failures, not just vars module errors - Correct the raw content caveat: markdown pages do not expose content via vars.content; point to pageFile.filepath for raw source and renderInnerPage() for rendered HTML --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8ab1043..4bc37c1 100644 --- a/README.md +++ b/README.md @@ -1069,19 +1069,20 @@ const date = page.vars.date For large sites with hundreds of pages, caching the result once per page reduces build time noticeably. -**`page.vars` can throw.** If a page vars module has a syntax error, a missing dependency, or a runtime error, accessing `.vars` will throw. Wrap accesses in `try/catch` when iterating all pages so one broken page does not abort the whole function: +**`page.vars` can throw.** If a page failed to initialize (often due to page vars module syntax errors, missing dependencies, or runtime errors), accessing `.vars` will throw. Wrap accesses in `try/catch` when iterating all pages so one broken page does not abort the whole function: ```js const posts = pages.filter(p => { try { - return p.vars.layout === 'article' && p.vars.date + const vars = p.vars + return vars.layout === 'article' && vars.date } catch { return false } }) ``` -**`page.vars.content` is raw source, not rendered HTML.** For markdown pages, `vars.content` is the raw markdown string read from the file. To get rendered HTML, call `page.renderInnerPage({ pages })`. +**Raw markdown source is not exposed as `page.vars.content` by default.** For markdown pages, `page.vars` contains front matter-derived values such as `title`, but does not automatically include the raw markdown body as `content`. If you need the raw source, read it from `page.pageInfo.pageFile.filepath`. To get rendered HTML, call `page.renderInnerPage({ pages })`. **`renderInnerPage()` is available.** `global.data.js` receives fully initialized `PageData` instances, so you can call `renderInnerPage()` here. See [Accessing rendered page content](#accessing-rendered-page-content) for usage and performance guidance. From 3046a1b3b606b15697bb625a7352ecdd46aa30b2 Mon Sep 17 00:00:00 2001 From: Bret Comnes Date: Sat, 18 Apr 2026 12:53:20 -0700 Subject: [PATCH 3/3] Fix wording in global.data.js caveats section --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4bc37c1..8613a95 100644 --- a/README.md +++ b/README.md @@ -1082,9 +1082,9 @@ const posts = pages.filter(p => { }) ``` -**Raw markdown source is not exposed as `page.vars.content` by default.** For markdown pages, `page.vars` contains front matter-derived values such as `title`, but does not automatically include the raw markdown body as `content`. If you need the raw source, read it from `page.pageInfo.pageFile.filepath`. To get rendered HTML, call `page.renderInnerPage({ pages })`. +**Raw markdown source is not exposed as `page.vars.content` by default.** For markdown pages, `page.vars` contains front matter-derived values such as `title`, but does not automatically include the raw markdown body as `content`. If you need the raw source, use `page.pageInfo.pageFile.filepath` to locate the source file on disk and read that file. To get rendered HTML, call `page.renderInnerPage({ pages })`. -**`renderInnerPage()` is available.** `global.data.js` receives fully initialized `PageData` instances, so you can call `renderInnerPage()` here. See [Accessing rendered page content](#accessing-rendered-page-content) for usage and performance guidance. +**`renderInnerPage()` is available.** `global.data.js` runs after page initialization has been attempted, and receives `PageData` instances (some may be uninitialized if they failed to initialize), so you can call `renderInnerPage()` here with the same care described above for `page.vars` and other page-dependent access. ### `esbuild.settings.ts`