Replies: 6 comments 15 replies
-
I'd favor (2), putting legacy support behind a flag, along with a good migration path (mostly docs). |
Beta Was this translation helpful? Give feedback.
-
I favour option 1 during 5.0 beta, with option 2 being viable for 5.0 stable. Reminder that historically, it's only been a small percentage of people who have run on beta versions. Many prefer to wait until stable versions, and the ones who do opt in to a beta version are typically the ones who are cool jumping through a few extra hoops to get it working. I would not want to offload the extra friction to existing projects/users! If, as I was kind of thinking/hoping, this is solved for 5 stable, then people with existing collections in So, my preference depends on when you think content layer will be compatible with |
Beta Was this translation helpful? Give feedback.
-
I guess content layer makes it kind of impossible to support implicit collections like we currently have, right? (Because there’s no way to know if Part of me wishes we could keep offering more or less the current behaviour with only the entry interface changes, so that the migration path for a user was focused entirely on internal code ( Not sure if this overlaps with the points you’ve explored @ascorbic, but could we also in theory enable the legacy behaviour on a per-collection basis while still dropping the implicit collection behaviour? i.e. something like import { defineCollection } from 'astro:content';
import { legacyLoader } from 'astro:loaders';
import { z } from 'astro/zod';
export const collections = {
docs: defineCollection({
loader: legacyLoader('docs'),
schema: z.object({ ... }),
}),
}; That would make gradual migrations a bit easier rather than forcing into a single on/off flag. |
Beta Was this translation helpful? Give feedback.
-
Can you reconsider exporting error ts(2305): Module '"astro:content"' has no exported member 'RenderResult'.
import type { RenderResult } from 'astro:content'; |
Beta Was this translation helpful? Give feedback.
-
I have a prototype of emulating current behaviour using glob. See withastro/astro#11976 |
Beta Was this translation helpful? Give feedback.
-
I've updated this with my proposal, and moved the other ideas behind a details tag |
Beta Was this translation helpful? Give feedback.
-
The Content Layer API is new way to define content collections that is available in Astro 4.14 behind a flag, and stable in Astro 5. It is designed to work alongside existing content collections.
Currently (Astro 4.14/ Astro 5 beta), any folder inside
src/content
is treated as a legacy content collection and processed in exactly the same way as before. This means there is a restriction on content collections that use the content layer API, meaning that they can't be in that directory. This is quite counter-intuitive.Proposal
By default, collections that use the the old types (content or data) are implemented using the glob loader, with extra backward-compat handling. This includes any collection without a
loader
defined.Any legacy content collections are handled like this:
glob
loader collection is defined, with patterns that match the previous handling (matchessrc/content/<collection name>/**/*.md
and other content extensions depending on installed integrations, with underscore-prefixed files and folders ignored)slug
field is added with the same format as beforerender()
method is added to the entry, so they can be called usingentry.render()
getEntryBySlug
is supportedLegacy data collections are handled like this:
glob
loader collection is defined, with patterns that match the previous handling (matchessrc/content/<collection name>/**/*{.json,.yaml}
and other data extensions, with underscore-prefixed files and folders ignored)getDataEntryById
is supportedWhile these emulate most of the features of legacy collections, they have these differences:
config.ts
. For legacy collections these can just be empty declarations: e.g.const blog = defineCollection({})
. Removing implicit collections means that we can allow content layer collections insrc/content
.layout
field is not supported in Markdownimage().refine()
is not supportedgetEntry
is typed asstring
, rather than having types for every entry.A new config flag
legacy.legacyContentCollections
is added for users that need the old behavior. When set, collections insrc/content
are processed in the same way as before rather than being implemented with glob - including implicit collections. When set, content layer collections are forbidden insrc/content
, and will fail a build if defined.There is a WIP implementation of this proposal in withastro/astro#11976
Previous proposals
This discussion is about several related issues around how to handle backward compatibility.Motivations:
src/content
is confusing. We should find a way allow it.Problems:
src/content
, even if they're not defined inconfig.ts
slug
field is not generated, andid
is the slug not the filename.getEntryBySlug
is not supported.render(entry)
notentry(render)
Possible solutions:
src/content
directory and generating collections for each directory does work (tried in PoC), though there's no clean way to exclude directories that are already used in a collectionslug
field to legacy collections and use the file as the id. Handling this via the schema is tough, because of all the ways zod schemas can be defined, so this may need to be handled elsewhere - though this means loader-specific logic outside of the loader which is a bit ick. I did quite a bit of PoC work on doing this via the schema and there are lots of edge cases but it is probably doable.getEntryBySlug
is already deprecated in4.x
, so removing support should be fineThe biggest problem is the conflicts in 1. There are no clean ways to determine if a folder is meant to use legacy collections if we allow new collections in
src/content
too.Options:
src/content
, and legacy collections handled with old codesrc/content
, and legacy collections handled with old code), otherwise content layer can usesrc/content
, and no legacy collections are parsed.config.ts
, and then emulate those using glob.Beta Was this translation helpful? Give feedback.
All reactions