---
title: Read content from a site
description: Read what you publish from a Worker over a service binding, from a Nuxt site, or from anywhere over HTTP with a read token.
section: guides
order: 2
---

# Read content from a site

Your site reads published content only: a draft, or the unpublished changes of an entry, never reach it. There are three ways in.

## From a Worker, over a service binding

A Worker on the same Cloudflare account binds the `Hollware` entrypoint of your Hollware Worker. No network, no token:

```jsonc
// wrangler.jsonc of the site
"services": [
  { "binding": "HOLLWARE", "service": "my-cms", "entrypoint": "Hollware" }
]
```

```ts
const answer = await env.HOLLWARE.getEntry('my-site', 'blog', 'hello-world', 'en', {
  formats: ['html'],
})
if (answer.outcome === 'ok') return new Response(answer.entry.html)
```

The binding has four methods, all read-only: `getEntry`, `listEntries`, `getTranslations` and `describeSite`. `getEntry` returns the Markdown, the Comark document or the HTML, as `formats` asks.

## From Nuxt

`@hollware/nuxt` does the reading for a Nuxt site:

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@hollware/nuxt'],
  hollware: { site: 'my-site' },
})
```

```vue
<script setup lang="ts">
const { data } = await useHollwareEntry('blog', 'en', 'hello-world')
</script>

<template>
  <h1>{{ data?.entry.frontmatter.title }}</h1>
  <HollwareContent :entry="data?.entry" />
</template>
```

On Cloudflare it uses the `HOLLWARE` binding; anywhere else, set `hollware.url` and a read token in `NUXT_HOLLWARE_TOKEN`. The token stays on the server: pages read through the site's own `/_hollware/` routes.

## Over HTTP, with a read token

The read API serves the same four reads at `/v1`:

```sh
curl -H "Authorization: Bearer hw_read_..." "http://localhost:5199/v1/blog/en/hello-world?formats=html"
```

| Request                                         | Answer                         |
| ----------------------------------------------- | ------------------------------ |
| `GET /v1/site`                                  | the site: locales, collections |
| `GET /v1/{collection}?locale&tag&limit&cursor` | a page of published entries    |
| `GET /v1/{collection}/{locale}/{slug}?formats=` | one entry                      |
| `GET /v1/{collection}/translations/{group}`     | the entries of a translation group |

Answers carry an ETag; send it back in `If-None-Match` to get a 304. The OpenAPI document is at `/v1/openapi.json`.

A **read token** (`hw_read_`) reads published content over this API and nothing else, so it can sit in a build, or even in a browser:

```sh
npx hollware token create --read --label my-site            # in the project, for the local database
npx hollware token create --read --label my-site --remote   # for the deployed one
```

Like every token, it is printed once: Hollware keeps only its hash. Locally the read API is at `http://localhost:5199/v1`; once deployed, at the public URL of your Hollware. `blog` is the starter's collection: use the names `describe_site` returns.

For a browser, list the origins of your pages in the site's config:

```ts
sites: { blog: { cors: { origins: ['https://example.com'] }, ... } }
```
