8 August 2026

Show Astro Draft Posts Locally but Hide Them in Production

A small Astro content-filtering pattern that makes draft posts visible during local development without publishing them.


While building this site I wanted draft articles to be visible when running Astro locally, but excluded from the production build.

A simple collection filter does it:

const articles = await getCollection(
  'articles',
  ({ data }) => import.meta.env.DEV || !data.draft
);

The logic is:

Development?
    ├── Yes → include the post
    └── No  → include only when draft is false

So a post can remain:

draft: true

while I work on it locally with:

npm run dev

but it will not be included by the same filter in a production build.

The same pattern can be used for TIL notes or other Astro content collections.

Why I prefer this

It keeps publishing state in the content itself while still allowing me to review the complete site locally.

Just remember that draft: true is not a security boundary. If the source repository is public, the Markdown file can still be visible in Git even if Astro does not publish the rendered page.