Skip to content

The V1-supported framework adapter. What the default template ships with, and how to customize it.

The Astro adapter (@grove-dev/astro) is the only V1-supported framework for Grove-powered spaces. The default template ships a fully working directory site that renders project-directory records out of the box.

V1 supported. The default template is the reference implementation. The Open Apps showcase uses it.

When you run pnpm dlx @grove-dev/cli@latest new my-space --framework astro, the template generates:

  • Astro 6.4+ site with @grove-dev/astro integration wired up.
  • Plain CSS + design tokens under src/styles.css (no Tailwind dependency required; Tailwind 4 is supported as an opt-in).
  • Home page (src/pages/index.astro) with hero, “Why this exists” intro, three record lens sections, explore-by-category, explore-by-stack, and contributors grid.
  • Blueprint-aware dynamic list page at src/pages/[slug]/index.astro — the same page renders /projects/, /resources/, and /entities/ from the configured blueprintConfig.routeSlug (no per-blueprint fork).
  • Blueprint-aware detail page at src/pages/[slug]/[recordSlug].astro — one page serves every record across every blueprint.
  • V0 alias redirect at src/pages/apps/[recordSlug].astro — any /apps/<slug> URL issues a 301 redirect to the V1 canonical /projects/<slug>. Keeps openapps-style bookmarks working.
  • About, contributors, and submit pages as Astro components.
  • llms.txt and llms-full.txt generated at build time (via grove llms).
  • sitemap.xml generated at build time (via grove sitemap).
  • 22 Astro components under packages/astro/src/components/ (Hero, ItemCard, IndexRow, Pagination, RecordSection, RefinePanel, ScoreBars, SmartLensTabs, ExploreByCategory, ExploreByStack, WhyThisExists, CurationGrid, ContributorsGrid, StackGrid, Icon, MinimalAbout, OriginalCollection, DecisionRow, FilterGroupMenu, FilterOptions, CategoryGrid — the V1 published ItemCard name is retained for downstream stability).
  • 1 layout under packages/astro/src/layouts/ (BaseLayout).
  • 11 GitHub Actions workflows generated by --github public mode (validate, build, deploy, sync-github-metadata, sync-contributors, cleanup-stale-records, update-records, …).
  • 6 provider-specific config files generated by --deploy (vercel.json, netlify.toml, wrangler.jsonc, GitHub Pages workflow, or a none stub).

Use the Astro adapter when:

  • You want a fully static site that deploys to any CDN.
  • The data is read-mostly (no server-side logic needed at request time).
  • You value fast page loads and small JS bundles.
  • You want Grove’s full design-token theming (primary color, radius, density) out of the box.

For server components, edge runtime, or React, see the Next.js adapter (roadmap only) or the SvelteKit adapter (roadmap only).

The Astro template is meant to be edited. Common customizations:

Override a component. Add a components: block to grove.config.ts:

export default defineConfig({
// ...
components: {
ItemCard: "./src/components/MyItemCard.astro",
},
});

The custom path replaces the default @grove-dev/astro component. The V1 canonical name for the index row is IndexRow and for the detail list is RecordSection; both can be overridden the same way.

Change the theme. Edit theme in grove.config.ts:

export default defineConfig({
// ...
theme: {
primaryColor: "#7c3aed",
radius: "round",
density: "compact",
},
});

The Astro template reads these and applies them to the design tokens in src/styles.css.

Add a page. Drop an .astro file under src/pages/ (e.g. src/pages/changelog.astro) and link to it from nav in grove.config.ts. Astro picks it up automatically.

Add a custom facet. Add a record field to your facets: list:

export default defineConfig({
// ...
facets: ["category", "stacks", "platforms", "tags", "license"],
});

The renderer exposes refinement controls for every listed facet on the /<blueprint-slug>/ index (e.g. /projects/).

The template’s pnpm build script chains the full pipeline:

pnpm run build:data # grove generate
pnpm run build:sitemap # grove sitemap
pnpm run build:llms # grove llms
astro build # Astro static build

Every step is a separate command. You can run them in isolation while developing:

Terminal window
grove generate # rebuild data/generated/records.{full,index}.json
pnpm dev # Astro dev server (auto-runs grove generate)
grove sitemap # regenerate public/sitemap.xml
grove llms # regenerate public/llms.txt + llms-full.txt
my-space/
├── astro.config.mjs # uses @grove-dev/astro integration
├── grove.config.ts # your site config
├── package.json
├── tsconfig.json
├── public/ # logo, OG image, llms.txt, robots.txt
│ ├── llms.txt
│ ├── llms-full.txt
│ ├── robots.txt
│ ├── og-image.svg
│ └── icons/stacks/ # SVG stack icons (33+ shipped)
├── .github/ # workflows + issue templates (11+ files)
│ ├── workflows/
│ └── ISSUE_TEMPLATE/
├── data/
│ ├── records/ # your YAML records go here
│ ├── decisions.yml # curator decisions
│ ├── overrides.yml # manual patches
│ └── generated/ # auto-generated JSON (gitignored)
├── scripts/ # build-llms.mjs, fetch-icons.mjs, …
└── src/
├── pages/
│ ├── index.astro
│ ├── about.astro
│ ├── contributors.astro
│ ├── submit.astro
│ ├── 404.astro
│ ├── apps/
│ │ └── [recordSlug].astro # V0 alias → 301 redirect
│ ├── [slug]/
│ │ ├── index.astro # list (blueprint-aware)
│ │ └── [recordSlug].astro # detail (blueprint-aware)
│ └── sitemap.xml.ts
├── data/
│ └── records.ts # typed loader for records.full.json
├── data/generated/
│ └── site-config.json # generated blueprint config
├── lib/
│ └── … # site-specific helpers (no business logic)
└── styles/
└── global.css # design tokens (--grove-*)

V0→V1 URL convention. The V0-published Astro template exposed /apps/<slug> as a static alias for the openapps-style directory. The V1 template uses the blueprint-aware dynamic route /<blueprint>/<record-slug> (e.g. /projects/coolify). The apps/[recordSlug].astro page is a 301 redirect so any existing /apps/<slug> bookmarks keep working.