🚀 Use Astro Integration ​
Camomilla ships with a first-class frontend integration for Astro: @camomillacms/astro-integration. It turns Camomilla into a fully headless CMS backend for an Astro site with zero boilerplate — auto-routing, SSR, SEO meta, template registration, caching, and ready-made components all handled by the integration.
IMPORTANT
Version compatibility — Camomilla 6.5 requires @camomillacms/astro-integration ≥ 0.7. The 6.5 release moves page-visibility gating server-side and adds the authenticated preview router and the public menus resolver; integration 0.7 is the first version that speaks this API. On camomilla 6.5, an older (0.6.x) integration would render non-public pages publicly. Conversely, integration 0.7 targets 6.5+ — see Use Page Lifecycle for the details.
Install ​
npm add @camomillacms/astro-integrationRegister the integration in your astro.config.mjs:
import camomilla from "@camomillacms/astro-integration";
import node from "@astrojs/node";
export default {
integrations: [
camomilla({
server: "http://localhost:8000", // your Camomilla server URL
autoRouting: true, // auto-create routes from the Camomilla API
templatesIndex: "./src/templates/index.js",
stylesIndex: "/src/styles/main.scss",
forwardedHeaders: ["X-Forwarded-Host", "X-Forwarded-Proto"],
enableTransitions: false,
}),
],
output: "server",
adapter: node({ mode: "standalone" }),
};WARNING
The integration runs in SSR mode only — set output: "server" and use the @astrojs/node adapter.
Key Features ​
- Auto Routing — routes are created on the fly from the Camomilla page API.
- SEO —
<title>, Open Graph, Twitter Card, schema.org JSON-LD are populated from the page response. - Templates — map Camomilla
templateidentifiers to.astrofiles via a single index module. - Error templates — register a generic
errortemplate plus per-status templates (404,500, …). - Draft pages — non-public pages return
404by default; append?preview=trueto preview. - Forwarded headers — configurable request-header forwarding so Camomilla knows the real host/proto.
- Cache — optional response cache with
memory,redis,valkey, ormemcachebackends andvaryOnHeaderssupport. - Transitions — works with Astro's view-transitions engine.
- Components — ready-made Astro components that consume Camomilla API shapes (see below).
Components ​
<CamomillaPicture> ​
Render a responsive <picture> from a Camomilla Media object. Uses the renditions / srcset fields produced by Camomilla's responsive rendition system (AVIF + WebP + original at sm/md/lg widths by default) and degrades gracefully to a plain <img> when no renditions exist.
---
import CamomillaPicture from '@camomillacms/astro-integration/components/CamomillaPicture.astro'
import type { CamomillaMedia } from '@camomillacms/astro-integration/types/camomillaMedia'
const media = Astro.locals.camomilla?.page?.template_data?.hero as CamomillaMedia
---
<CamomillaPicture
media={media}
sizes="(min-width: 1024px) 1600px, 100vw"
loading="eager"
fetchpriority="high"
class="hero-img"
/>Output:
<picture>
<source type="image/avif" srcset="…sm-avif.avif 400w, …md-avif.avif 800w, …lg-avif.avif 1600w" sizes="…">
<source type="image/webp" srcset="…sm-webp.webp 400w, …md-webp.webp 800w, …lg-webp.webp 1600w" sizes="…">
<img src="…lg-original.jpg" srcset="…" sizes="…" alt="…" loading="lazy" decoding="async" width="1980" height="1319">
</picture>The browser picks the first <source> it understands; the inner <img> is the universal fallback. width / height are pre-filled from media.image_props to prevent layout shift.
Props:
| Prop | Default | Description |
|---|---|---|
media | — | Required. The Media object from Camomilla's REST API. |
sizes | — | Standard HTML sizes attribute, applied to every <source> and the <img>. |
alt | media.alt_text | Image alt text. Falls back to the Media's alt_text. |
loading | 'lazy' | Use 'eager' for above-the-fold images. |
decoding | 'async' | Native decoding hint. |
fetchpriority | — | 'high' / 'low' / 'auto'. |
formats | ['avif', 'webp'] | <source> preference order. |
fallbackFormat | 'original' | Which rendition set feeds the fallback <img>. |
class | — | Class applied to the <img>. Use this for Tailwind/CSS. |
pictureClass | — | Class applied to the <picture>. |
All other props are forwarded to the <img> as HTML attributes.
<SeoHead> and <MainLayout> ​
The integration also exposes a SeoHead component (auto-wired inside MainLayout) that populates the document head from Camomilla's page SEO fields, and a MainLayout that injects global styles and optional view-transitions. Both are consumed automatically by the template router — you rarely need to import them directly.
Templates ​
Register your Astro templates in a single index module (./src/templates/index.js):
import MyTemplate from './mytemplate.astro'
import ErrorTemplate from './error.astro'
import NotFoundTemplate from './404.astro'
export default {
'my-template': MyTemplate,
error: ErrorTemplate,
'404': NotFoundTemplate,
}The Camomilla-side template identifier on each page selects the component. Error statuses (404, 500, …) match first, falling back to the generic error template.
Accessing page data ​
Camomilla data is injected into Astro.locals.camomilla by the integration middleware:
---
const page = Astro.locals.camomilla?.page // the current CamomillaPage
const user = Astro.locals.camomilla?.user // current user (if authenticated)
const status = Astro.locals.camomilla?.response?.status
const error = Astro.locals.camomilla?.error
---Cache ​
Enable caching of the entire Astro response to keep pages fast under load:
camomilla({
cache: {
backend: 'redis', // 'memory' | 'redis' | 'valkey' | 'memcache'
location: 'redis://user:pass@localhost:6379',
ttl: 60 * 60 * 1000, // ms, or "1h" / "30m" / "45s"
keyPrefix: 'astro-camomilla-integration',
varyOnHeaders: ['Cookie', 'User-Agent'], // cache separately per header value
},
})varyOnHeaders is the recommended knob for splitting the cache between authenticated and anonymous users (or per-locale via Accept-Language).
More ​
Full documentation, source code, and issue tracker: github.com/camomillacms/astro-camomilla-integration.