Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft frontmatter flag not respected in collection #6400

Closed
1 task done
gotofritz opened this issue Mar 1, 2023 · 6 comments
Closed
1 task done

Draft frontmatter flag not respected in collection #6400

gotofritz opened this issue Mar 1, 2023 · 6 comments
Labels
- P2: has workaround Bug, but has workaround (priority) feat: content collections Related to the Content Collections feature (scope)

Comments

@gotofritz
Copy link

What version of astro are you using?

2.0.2

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

pnpm

What operating system are you using?

Mac

Describe the Bug

draft: true in frontmatter of pages is respected, but in frontmatter of collections it isn't when generating static site.

As a workaround one can create a filter when calling getCollection and also getStaticPath

await getCollection("post", ({ data }) => import.meta.env.DEV || !data?.draft))

But that's not consistent with pages (where ItJustWorks) or with user expectations

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-tlp8uq

Participation

  • I am willing to submit a pull request for this issue.
@gotofritz
Copy link
Author

Also, the type definition for the filter function I suggested in the workaround doesn't make sense, and doesn't match the documentation.

Type definition, .astro/types.d.ts:

	export function getCollection<C extends keyof typeof entryMap, E extends CollectionEntry<C>>(
		collection: C,
		filter?: (entry: CollectionEntry<C>) => entry is E
	): Promise<E[]>;

Documentation:

await getCollection('blog', ({ data }) => {
  return data.draft !== true;
});

According to the doc the return type of the filter function should be boolean, not entry. I believe this is correct (at any rate, it does the job) and the type definition wrong

@ematipico
Copy link
Member

@gotofritz

The getCollection function is defined as an overloaded function:

https://github.com/withastro/astro/blob/main/packages/astro/src/content/template/types.d.ts#L64-L71

The second definition aligns with the documentation. unknown is correct because that's how typescript defines their filter predicate.

@ematipico ematipico added - P2: has workaround Bug, but has workaround (priority) feat: content collections Related to the Content Collections feature (scope) labels Mar 9, 2023
@gotofritz
Copy link
Author

Yeah, I know TS does it that way, with unknown instead of boolean - wrongly, but as I understand the correct way broke too many existing code But the types.d.ts I get is not overloaded, it only has the first definition, which doesn't work. This is my types.d.ts

      ....
	export function getEntryBySlug<
		C extends keyof typeof entryMap,
		E extends ValidEntrySlug<C> | (string & {})
	>(
		collection: C,
		// Note that this has to accept a regular string too, for SSR
		entrySlug: E
	): E extends ValidEntrySlug<C>
		? Promise<CollectionEntry<C>>
		: Promise<CollectionEntry<C> | undefined>;
	export function getCollection<C extends keyof typeof entryMap, E extends CollectionEntry<C>>(
		collection: C,
		filter?: (entry: CollectionEntry<C>) => entry is E
	): Promise<E[]>;

	type InferEntrySchema<C extends keyof typeof entryMap> = import('astro/zod').infer<
		Required<ContentConfig['collections'][C]>['schema']
	>;
     ...

@walter9388
Copy link
Contributor

Is there any update on this?

It took me a long time to figure out why my markdown drafts were still being built in production, and after finally realising it was to do with the getCollection function, I have since solved my issues with the above mentioned filter function:

await getCollection("post", ({ data }) => import.meta.env.DEV || !data?.draft))

Regardless of the status of the bugfix, it feels like a small note acknowledging the bug in the documentation next to the drafts section would have saved me a lot time, and I'm sure it will help many others until the problem is resolved.

@natemoo-re
Copy link
Member

After much discussion with the team, we've made the decision to deprecate the drafts feature in Astro 3.0. It was only ever supported in .md and .mdx files inside of the src/pages/ directory, but never implemented in the Content Collections API.

Drafts were introduced back before Astro 1.0, when Astro was purely a static site generator and .md/x pages were our recommended way of working with content. Since then, Astro's capabilities and scope have grown to accommodate many different hosts and server runtimes. As such, we feel that the drafts feature as originally designed doesn't fit with our current approach to content.

Despite this deprecation, we understand the need for previewing unpublished content. There is an ongoing roadmap discussion about supporting preview deployments for headless CMSs. Hopefully whatever eventual API emerges from that discussion can also accommodate local content. In the meantime, manually filtering your Content Collection posts using this approach is a perfectly valid way to implement drafts in userland.

await getCollection("post", ({ data }) => import.meta.env.DEV || !data?.draft))

@natemoo-re natemoo-re closed this as not planned Won't fix, can't repro, duplicate, stale Aug 17, 2023
@gotofritz
Copy link
Author

This is so flipping disappointing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P2: has workaround Bug, but has workaround (priority) feat: content collections Related to the Content Collections feature (scope)
Projects
None yet
Development

No branches or pull requests

4 participants