Post visibility refactor: isPostVisible, siteMeta, sitemap filter#78
Merged
Conversation
Replaces scattered `!p.frontmatter.draft` filters with a single `isPostVisible(frontmatter)` helper used by BaseLayout, llms.txt, llms-full.txt, and the markdown endpoint. Adds PostFrontmatter.hidden alongside the existing draft field: - draft: hidden in PROD, visible in dev (unchanged semantics) - hidden: never rendered (new) Non-breaking: existing `draft: true` posts behave identically.
Gives downstream a single file to override instead of duplicating the constants across llms.txt.ts and BaseLayout.astro. Also drops the two `TODO(downstream)` comments — the override point is now explicit.
Previously, @astrojs/sitemap saw every prerendered page, so posts with `hidden: true` (or `draft: true` in prod) leaked into sitemap-index.xml even though they were filtered out of BaseLayout's post list and the llms.txt endpoints. getHiddenPostUrls() scans /posts at config-load time, extracts the set of hidden URL paths, and the sitemap `filter` hook drops them. Zaduma's own demo content has no hidden/draft posts, so behavior is unchanged — but downstream consumers (e.g. sites that stash unpublished notes under /posts) now stay out of the sitemap automatically.
Comment on lines
+49
to
+52
| /** Hidden in PROD, visible in dev. */ | ||
| draft?: boolean; | ||
| /** Never rendered, including in dev. */ | ||
| hidden?: boolean; |
There was a problem hiding this comment.
🔴 Incomplete migration: [...path].astro still generates pages for hidden posts
The PR introduces hidden on PostFrontmatter (documented as "Never rendered, including in dev") and the centralized isPostVisible helper, but src/pages/[...path].astro:24-25 still uses the old !post.frontmatter.draft check in a PROD-only guard. This means posts with hidden: true will still have full HTML pages generated and accessible at their URL in both dev and production. The same incomplete migration applies to src/pages/index.astro:14-15, which will still list hidden posts on the homepage.
Prompt for agents
The PR introduces the `hidden` field on PostFrontmatter and creates `isPostVisible` to centralize visibility logic, but two critical pages were not updated:
1. src/pages/[...path].astro (lines 24-25): This is the main route that generates HTML pages for each post. It still uses the old pattern `if (import.meta.env.PROD) { posts = posts.filter((post) => !post.frontmatter.draft); }`. It needs to import and use `isPostVisible` instead, so hidden posts never get page routes.
2. src/pages/index.astro (lines 14-15): This is the homepage post listing. Same old pattern. Needs to use `isPostVisible` so hidden posts don't appear in the listing.
Both files should be updated to match the pattern used in BaseLayout.astro, [...path].md.ts, llms.txt.ts, and llms-full.txt.ts — replace the PROD-only draft check with `.filter(p => isPostVisible(p.frontmatter))`.
Additionally, src/pages/rss.xml.ts has no visibility filtering at all and should also be updated.
Was this helpful? React with 👍 or 👎 to provide feedback.
Replace PROD-only draft filter with isPostVisible in [...path].astro, index.astro, and add visibility filtering to rss.xml.ts so hidden posts are excluded from page routes, the homepage listing, and the RSS feed. Also ignore *.md in eslint (root README failed TS parser).
Sitemap exclusion derived from hiddenPostUrls treated draft:true as
hidden unconditionally and built /slug/ (trailing slash), drifting from
the runtime isPostVisible policy (draft hidden only in PROD) and risking
silent slash-mismatch re-inclusion.
- isPostVisible takes optional { isProd } so the build-time scanner reuses
the exact same policy (import.meta.env-safe outside Vite)
- getHiddenPostPaths (was getHiddenPostUrls) applies isPostVisible and
returns canonical no-trailing-slash paths via shared postPath helper
- postPath: single path-normalization rule, used by both the scanner and
urlOutsideOfPagesDirPlugin
- sitemap filter strips trailing slash on both sides before lookup
Attempt to fix CI hang on 'playwright install --with-deps chromium'.
Add timeout-minutes guards and non-interactive apt env to surface which half of '--with-deps' hangs and fail fast instead of stalling.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three small, independent refactors that emerged while making haspar.us agent-ready:
isPostVisiblehelper — replaces scattered `!p.frontmatter.draft` filters across `BaseLayout`, `llms.txt`, `llms-full.txt`, and the markdown endpoint. Adds a new `hidden` frontmatter flag (never rendered, even in dev) alongside the existing `draft` (hidden in prod). Non-breaking.`src/lib/siteMeta.ts` — single override point for `SITE_NAME` + `SITE_BLURB`, replacing the two `TODO(downstream)` comments in `llms.txt.ts` and `BaseLayout.astro`. Downstream consumers can extend this module with `AUTHOR` and thread it through their own `PostLayout` / `rss`.
Sitemap filter — `@astrojs/sitemap` was previously unfiltered, so hidden/draft posts leaked into `sitemap-index.xml` even though every other endpoint (llms.txt, BaseLayout post list) filtered them. `getHiddenPostUrls()` scans `/posts` at config-load time and passes hidden URL paths to sitemap's `filter` hook. No change for zaduma's own demo content (no hidden posts), but downstream sites (e.g. haspar.us has `nie-trzeba` and `rpg` marked `hidden`) now stay out of the sitemap automatically.
Test plan