Skip to content

Add url field to PageInfo for canonical URL access in layouts#250

Merged
bcomnes merged 2 commits into
masterfrom
fix/page-url-var
May 24, 2026
Merged

Add url field to PageInfo for canonical URL access in layouts#250
bcomnes merged 2 commits into
masterfrom
fix/page-url-var

Conversation

@bcomnes
Copy link
Copy Markdown
Owner

@bcomnes bcomnes commented Apr 18, 2026

Closes #238

What changed

Adds a url field to the PageInfo object, computed once at page identification time from path and outputName. Layouts can now use page.url directly instead of manually reconstructing the URL from page.path.

// Before: fragile, wrong for loose markdown pages
export default function rootLayout ({ children, vars, page }) {
  const pageUrl = page.path ? '/' + page.path + '/' : '/'
  const canonicalUrl = `${vars.siteUrl}${pageUrl}`
}

// After
export default function rootLayout ({ children, vars, page }) {
  const canonicalUrl = `${vars.siteUrl}${page.url}`
}

URL derivation rules

  • Index pages (outputName === 'index.html'): trailing-slash URL — /blog/my-post/, or / for the root
  • Non-index pages (loose markdown): URL includes the filename — /blog/loose-page.html

Path separators are normalized via fsPathToUrlPath for Windows safety.

Why page.url instead of vars.pageUrl

url is a fact about the page derived from its filesystem location, not a user-configurable variable. It belongs on PageInfo alongside path and outputName, not injected into the user variable cascade. Layouts already receive page directly.

Also in this PR

  • @types/pretty installed, removing the // @ts-expect-error on the pretty import
  • Resolved pre-existing // @ts-ignore in PageData.vars with a targeted /** @type {T} */ cast
  • Fixed pretty() call-site type error (Awaited<V> → cast to string)
  • README updated to document page.url and replace manual path construction in examples

Copilot AI review requested due to automatic review settings April 18, 2026 18:43
@coveralls
Copy link
Copy Markdown

coveralls commented Apr 18, 2026

Coverage Report for CI Build 26374300398

Coverage increased (+0.5%) to 92.658%

Details

  • Coverage increased (+0.5%) from the base build.
  • Patch coverage: 33 of 33 lines across 3 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 4131
Covered Lines: 3911
Line Coverage: 94.67%
Relevant Branches: 595
Covered Branches: 468
Branch Coverage: 78.66%
Branches in Coverage %: Yes
Coverage Strength: 73.92 hits per line

💛 - Coveralls

Copy link
Copy Markdown
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 PR aims to make canonical URL construction easier in layouts by automatically injecting a pageUrl value into PageData.vars, derived from pageInfo.

Changes:

  • Inject pageUrl into the base of the vars merge inside PageData.vars, allowing user-defined pageUrl to override it via later spreads.
Comments suppressed due to low confidence (1)

lib/build-pages/page-data.js:149

  • New public-ish behavior (vars.pageUrl) isn’t covered by tests. The repo already has node:test coverage for build behavior (eg test-cases/general-features/index.test.js). Please add a regression test that asserts vars.pageUrl (or an HTML marker rendered from it) for both an index page (/some-dir/) and a loose markdown page (/some-dir/file.html), and ideally cover Windows path normalization as well.
      pageUrl: this.pageInfo.path ? `/${this.pageInfo.path}/` : '/',
      ...globalVars,
      ...globalDataVars,
      ...pageVars,
      ...builderVars,
    }

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

Comment thread lib/build-pages/page-data.js Outdated
Comment thread lib/build-pages/page-data.js Outdated
Copy link
Copy Markdown
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 PR makes vars.pageUrl available to every rendered page by computing it from pageInfo inside PageData.vars, allowing layouts to build canonical/OG URLs without duplicating the project’s URL-construction convention.

Changes:

  • Injects a computed pageUrl into PageData.vars at the base of the vars merge (so user overrides still win).
  • Computes pageUrl with special handling for index.html (trailing-slash URLs) vs non-index outputs (include filename).
  • Normalizes URL paths via fsPathToUrlPath() for cross-platform (Windows) safety.

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

Comment thread lib/build-pages/page-data.js Outdated
Copy link
Copy Markdown
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

Adds automatic vars.pageUrl injection to every page so layouts can build canonical URLs without manually reconstructing URL path conventions.

Changes:

  • Inject pageUrl into PageData.vars at the lowest precedence so user-defined vars can override it.
  • Compute pageUrl based on pageInfo.path + outputName, mapping index.html to trailing-slash URLs and including filenames for non-index outputs.
  • Normalize path separators via fsPathToUrlPath() for cross-platform URL consistency.

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

Comment thread lib/build-pages/page-data.js Outdated
Comment thread lib/build-pages/page-data.js Outdated
Comment thread lib/build-pages/page-data.js Outdated
@bcomnes
Copy link
Copy Markdown
Owner Author

bcomnes commented Apr 20, 2026

This looks ready to go. It just needs readme docs and the above questions resolved.

@bcomnes bcomnes force-pushed the fix/page-url-var branch from 10a9284 to 691dd09 Compare May 24, 2026 21:28
@socket-security
Copy link
Copy Markdown

socket-security Bot commented May 24, 2026

Every page now gets a pageUrl derived from pageInfo.path so layouts can
build canonical URLs without manually computing the path-to-URL conversion.
User-supplied pageUrl in pageVars or globalVars still takes precedence.

Closes #238

Fix pageUrl for loose markdown pages and Windows path separators

Loose markdown files (not page.md/README.md) have outputName set to
their slug.html rather than index.html, so the previous formula
produced an incorrect directory-style URL for them.

The URL is now derived from outputName: index pages get a trailing slash,
non-index pages include the filename. fsPathToUrlPath is used to
normalize any OS-specific path separators.

Extract computePageUrl helper and add unit tests for URL derivation rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Remove unnecessary #computePageUrl wrapper method

Fix pretty types

Improve typecast

Document pageUrl variable injection in vars
@bcomnes bcomnes force-pushed the fix/page-url-var branch from a150ea7 to b138886 Compare May 24, 2026 22:05
@bcomnes bcomnes changed the title Inject pageUrl into page vars automatically Add url field to PageInfo for canonical URL access in layouts May 24, 2026
@bcomnes bcomnes merged commit f47bb96 into master May 24, 2026
10 checks passed
@bcomnes bcomnes deleted the fix/page-url-var branch May 24, 2026 22:20
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.

pageUrl not available to layouts for directly-rendered pages

3 participants