Skip to content

Content Collections

If you have a folder of .ly files, lilypondLoader() turns that folder into an Astro content collection. Each file becomes one entry, with header info like title and composer extracted for you.

Import lilypondLoader from astro-lilypond/loader and pass it to defineCollection() in your content.config.ts.

src/content.config.ts
import { defineCollection } from "astro:content";
import { lilypondLoader } from "astro-lilypond/loader";
export const collections = {
scores: defineCollection({
loader: lilypondLoader({ base: "./src/content/scores" }),
}),
};

Read the collection with getCollection(), then pass each entry’s data to the content of <Score>:

MyScores.astro
---
import { getCollection } from "astro:content";
import { Score } from "astro-lilypond";
const scores = await getCollection("scores");
---
<ul>
{scores.map((score) => (
<li>
<h3>{score.data.meta.title}</h3>
<Score content={score.data} />
</li>
))}
</ul>

Use getEntry() with the collection name and an entry’s id:

MyScore.astro
---
import { getEntry } from "astro:content";
import { Score } from "astro-lilypond";
const sonata = await getEntry("scores", "sonata");
---
<h3>{sonata.data.meta.title}</h3>
<Score content={sonata.data} />

The id is the file’s path relative to base, minus any file extension:

File (relative to base) Entry id
sonata.ly sonata
preludes/prelude-1.ly preludes/prelude-1
works/op-27/moonlight.lilypond works/op-27/moonlight

You can customize how ids are generated by setting generateId on the lilypondLoader config.

Each entry’s data.meta includes fields from your .ly file’s \header such as title, composer, and instrument.

MyScore.astro
---
import { getEntry } from "astro:content";
import { Score } from "astro-lilypond";
const entry = await getEntry("scores", "my-score");
---
<h3>{entry.data.meta.title}</h3>
<p>By {entry.data.meta.composer} for {entry.data.meta.instrument}</p>
<Score content={entry.data} />

When you need a downloadable PDF, call getScore() with pdf: true. For multiple entries, call it once per entry with Promise.all:

MyScore.astro
---
import { getEntry } from "astro:content";
import { getScore } from "astro-lilypond";
const sonata = await getEntry("scores", "sonata");
const { Score, pdf } = await getScore(sonata.data, { pdf: true });
---
<h3>{sonata.data.meta.title}</h3>
<Score />
<a href={pdf.src} download>Download PDF</a>

See the component reference for getScore()’s other return values, like pages and raw.