#12047 21b5e80
Thanks @rgodha24! - Adds a new optional parser
property to the built-in file()
loader for content collections to support additional file types such as toml
and csv
.
The file()
loader now accepts a second argument that defines a parser
function. This allows you to specify a custom parser (e.g. toml.parse
or csv-parse
) to create a collection from a file's contents. The file()
loader will automatically detect and parse JSON and YAML files (based on their file extension) with no need for a parser
.
This works with any type of custom file formats including csv
and toml
. The following example defines a content collection dogs
using a .toml
file.
[[dogs]]
id = "..."
age = "..."
[[dogs]]
id = "..."
age = "..."
After importing TOML's parser, you can load the dogs
collection into your project by passing both a file path and parser
to the file()
loader.
import { defineCollection } from "astro:content"
import { file } from "astro/loaders"
import { parse as parseToml } from "toml"
const dogs = defineCollection({
loader: file("src/data/dogs.toml", { parser: (text) => parseToml(text).dogs }),
schema: /* ... */
})
// it also works with CSVs!
import { parse as parseCsv } from "csv-parse/sync";
const cats = defineCollection({
loader: file("src/data/cats.csv", { parser: (text) => parseCsv(text, { columns: true, skipEmptyLines: true })})
});
The parser
argument also allows you to load a single collection from a nested JSON document. For example, this JSON file contains multiple collections:
{ "dogs": [{}], "cats": [{}] }
You can seperate these collections by passing a custom parser
to the file()
loader like so:
const dogs = defineCollection({
loader: file('src/data/pets.json', { parser: (text) => JSON.parse(text).dogs }),
});
const cats = defineCollection({
loader: file('src/data/pets.json', { parser: (text) => JSON.parse(text).cats }),
});
And it continues to work with maps of id
to data
bubbles:
breed: 'Goldfish'
age: 2
finn:
breed: 'Betta'
age: 1
const fish = defineCollection({
loader: file('src/data/fish.yaml'),
schema: z.object({ breed: z.string(), age: z.number() }),
});
#11963 0a1036e
Thanks @florian-lefebvre! - Adds a new createCodegenDir()
function to the astro:config:setup
hook in the Integrations API
In 4.14, we introduced the injectTypes
utility on the astro:config:done
hook. It can create .d.ts
files and make their types available to user's projects automatically. Under the hood, it creates a file in <root>/.astro/integrations/<normalized_integration_name>
.
While the .astro
directory has always been the preferred place to write code generated files, it has also been prone to mistakes. For example, you can write a .astro/types.d.ts
file, breaking Astro types. Or you can create a file that overrides a file created by another integration.
In this release, <root>/.astro/integrations/<normalized_integration_name>
can now be retrieved in the astro:config:setup
hook by calling createCodegenDir()
. It allows you to have a dedicated folder, avoiding conflicts with another integration or Astro itself. This directory is created by calling this function so it's safe to write files to it directly:
import { writeFileSync } from 'node:fs';
const integration = {
name: 'my-integration',
hooks: {
'astro:config:setup': ({ createCodegenDir }) => {
const codegenDir = createCodegenDir();
writeFileSync(new URL('cache.json', codegenDir), '{}', 'utf-8');
},
},
};
#12081 8679954
Thanks @florian-lefebvre! - Removes the experimental contentCollectionsCache
introduced in 3.5.0
.
Astro Content Layer API independently solves some of the caching and performance issues with legacy content collections that this strategy attempted to address. This feature has been replaced with continued work on improvements to the content layer. If you were using this experimental feature, you must now remove the flag from your Astro config as it no longer exists:
export default defineConfig({
experimental: {
- contentCollectionsCache: true
}
})
The cacheManifest
boolean argument is no longer passed to the astro:build:done
integration hook:
const integration = {
name: "my-integration",
hooks: {
"astro:build:done": ({
- cacheManifest,
logger
}) => {}
}
}