Astro Setup
The @wollycms/astro package provides a typed client, components, and helpers for building Astro sites powered by WollyCMS.
Installation
Section titled “Installation”npm install @wollycms/astroCreate the client
Section titled “Create the client”Create src/lib/wolly.ts:
import { createClient } from '@wollycms/astro';
export const wolly = createClient({ apiUrl: import.meta.env.CMS_API_URL || 'http://localhost:4321/api/content',});Add the environment variable to your .env:
CMS_API_URL=http://localhost:4321/api/contentCloudflare Workers configuration
Section titled “Cloudflare Workers configuration”When deploying your Astro frontend to Cloudflare Workers, the import.meta.env approach works for build-time values. For runtime configuration (where the CMS URL might differ per environment), use middleware to read from cloudflare:workers env bindings.
Set up the Astro adapter
Section titled “Set up the Astro adapter”npm install @astrojs/cloudflareimport { defineConfig } from 'astro/config';import cloudflare from '@astrojs/cloudflare';
export default defineConfig({ output: 'server', adapter: cloudflare(),});Create middleware for runtime env
Section titled “Create middleware for runtime env”Create src/middleware.ts:
import { defineMiddleware } from 'astro:middleware';import { createClient } from '@wollycms/astro';
export const onRequest = defineMiddleware(async (context, next) => { // On Cloudflare Workers, read the binding const runtime = context.locals.runtime; const cmsBaseUrl = runtime?.env?.CMS_API_URL || import.meta.env.CMS_API_URL || 'http://localhost:4321/api/content';
context.locals.wolly = createClient({ apiUrl: cmsBaseUrl });
return next();});Add the type declaration in src/env.d.ts:
/// <reference types="astro/client" />
declare namespace App { interface Locals { wolly: import('@wollycms/astro').WollyClient; runtime?: { env: { CMS_API_URL?: string; }; }; }}Then use Astro.locals.wolly in your pages instead of the static import:
---const wolly = Astro.locals.wolly;const page = await wolly.pages.getBySlug('home');---Add the binding to wrangler.toml
Section titled “Add the binding to wrangler.toml”[vars]CMS_API_URL = "https://cms.example.com/api/content"Create the block mapping
Section titled “Create the block mapping”Create src/lib/blocks.ts to map block type slugs to Astro components:
export { default as hero } from '../blocks/Hero.astro';export { default as rich_text } from '../blocks/RichText.astro';export { default as image } from '../blocks/ImageBlock.astro';export { default as cta } from '../blocks/CTA.astro';Create the catch-all route
Section titled “Create the catch-all route”Create src/pages/[...slug].astro:
---import Layout from '../layouts/Default.astro';import BlockRenderer from '@wollycms/astro/components/BlockRenderer.astro';import { wolly } from '../lib/wolly';import * as blocks from '../lib/blocks';
const slug = Astro.params.slug || 'home';const page = await wolly.pages.getBySlug(slug);---
<Layout title={page.title}> <BlockRenderer blocks={page.regions.hero ?? []} region="hero" components={blocks} /> <BlockRenderer blocks={page.regions.content ?? []} region="content" components={blocks} /></Layout>Client API reference
Section titled “Client API reference”The WollyClient instance exposes these namespaces:
| Namespace | Methods |
|---|---|
pages | getBySlug(slug), list(params?) |
menus | get(slug, depth?) |
taxonomies | getTerms(slug) |
media | getInfo(id), getVariant(id, variant), url(id, variant?) |
search | query(q, options?) |
redirects | list() |
config | get() |
schemas | get() |
trackingScripts | getForPage(slug?) |
All methods return typed responses matching the interfaces exported from @wollycms/astro.