---
title: Astro
description: Lee lo que publicas desde un sitio Astro con @hollware/astro, al pedir la página o al compilar, y renderízalo con tus propios componentes de Astro.
section: frameworks
order: 2
---

# Astro

`@hollware/astro` le da a la content layer de Astro dos loaders, y dos componentes que renderizan lo que cargan.

```sh
npm install @hollware/astro
```

## Leer al pedir la página

Una **live collection** lee en cada solicitud, así que lo que publicas aparece en la siguiente, sin recompilar. En Cloudflare, vincula tu Worker de Hollware en el `wrangler.jsonc` del sitio:

```jsonc
"services": [{ "binding": "HOLLWARE", "service": "my-cms", "entrypoint": "Hollware" }]
```

```ts
// src/live.config.ts
import { env } from 'cloudflare:workers'
import { defineLiveCollection } from 'astro/content/config'
import { hollwareBinding, hollwareLiveLoader } from '@hollware/astro'

const blog = defineLiveCollection({
  loader: hollwareLiveLoader({
    site: 'my-site',
    collection: 'blog',
    locale: 'es',
    reader: () => hollwareBinding(env.HOLLWARE),
  }),
})
export const collections = { blog }
```

Haz una colección por locale. El `id` de una entrada es su slug y su `data` el frontmatter, con los campos que llena Hollware ya llenos.

## Leer al compilar

Para un sitio estático, `hollwareLoader` en `src/content.config.ts` lee una vez cada entrada publicada, al compilar, por HTTP con un token de lectura (`npx hollware token create --read`):

```ts
// src/content.config.ts
import { defineCollection } from 'astro:content'
import { hollwareLoader } from '@hollware/astro'

const blog = defineCollection({
  loader: hollwareLoader({
    site: 'my-site',
    collection: 'blog',
    locale: 'es',
    url: 'https://cms.example.com',
    token: process.env.HOLLWARE_TOKEN ?? '',
  }),
})
export const collections = { blog }
```

Dale a `defineCollection` un `schema` para validar el frontmatter, como con cualquier loader.

## Renderiza una entrada

```astro
---
import HollwareContent from '@hollware/astro/HollwareContent.astro'
import HollwareImage from '@hollware/astro/HollwareImage.astro'
import { getLiveEntry } from 'astro:content'
import Callout from '../components/Callout.astro'

const { entry } = await getLiveEntry('blog', Astro.params.slug!)
if (!entry) return new Response('Not found', { status: 404 })
---

<h1>{entry.data.title}</h1>
<HollwareImage entry={entry} field="img" />
<HollwareContent entry={entry} components={{ callout: Callout }} />
```

- **`HollwareContent.astro`** renderiza la entrada desde su documento, con tus propios componentes de Astro para los componentes de tus entradas: `::callout{type="tip"}` le pasa a `Callout.astro` la prop `type` y su contenido en el `<slot />` por defecto. Un elemento sin asignar se renderiza como su etiqueta. Pasa por las mismas reglas que el HTML que hace Hollware, así que nada de una entrada ejecuta un script.
- **`HollwareImage.astro`** renderiza la imagen que guarda un campo del frontmatter, con su alt, su tamaño y el `srcset` de sus copias. Cualquier atributo que le des gana.

También puedes usar `render(entry)` de Astro: su `<Content />` es el HTML que hizo Hollware, y no necesita componentes tuyos.

## Listas y traducciones

`getLiveCollection('blog', { tag, limit })` lista las entradas, sin su cuerpo, cada una con las imágenes de su frontmatter para `HollwareImage.astro`. `hollwareTranslations(options, group)` entrega el `{ locale, slug }` de cada entrada de un grupo de traducción, para enlazarlas.

## Vistas previas

Una live collection muestra vistas previas de borradores. Agrega el middleware, que cambia el enlace de vista previa del admin por una cookie:

```ts
// src/middleware.ts
import { hollwarePreview } from '@hollware/astro'
export const onRequest = hollwarePreview()
```

```astro
---
import { refusePreview } from '@hollware/astro'
const preview = Astro.locals.hollwarePreview
const { entry, error } = await getLiveEntry('blog', { id: Astro.params.slug!, preview })
if (error) refusePreview(Astro.locals, error)
---
```

Con un token, la entrada es su última revisión, borrador incluido, y la página nunca se guarda en caché. Un token vencido es un `error`, nunca la versión publicada. Una colección de compilación no tiene vistas previas: una página estática se compila una vez, para todos.

## Un sitio completo

`examples/astro-blog` en el repositorio es un blog en Astro sobre un Worker que lee el playground en cada solicitud, con su callout como un componente propio.
