Frameworks
Nuxt
Read and render what you publish from a Nuxt site with @hollware/nuxt, over a service binding or a read token, with previews and images ready.
Nuxt
@hollware/nuxt is a Nuxt module: composables that read published content, components that render it, previews of drafts, and a cache that Hollware purges when you publish.
npm install @hollware/nuxtConfigure it
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@hollware/nuxt'],
hollware: { site: 'my-site' },
nitro: { preset: 'cloudflare_module', cloudflare: { deployConfig: true, nodeCompat: false } },
})On Cloudflare, bind your Hollware Worker in the site's wrangler.jsonc, and the module reads over it, with no network and no token:
"services": [{ "binding": "HOLLWARE", "service": "my-cms", "entrypoint": "Hollware" }]Anywhere else, set hollware.url to the address of your Hollware and a read token (npx hollware token create --read) in NUXT_HOLLWARE_TOKEN. The token stays on the server: pages read through the site's own /_hollware/ routes.
Show an entry
<script setup lang="ts">
const route = useRoute()
const { data } = await useHollwareEntry('blog', 'en', route.params.slug as string)
</script>
<template>
<article v-if="data">
<h1>{{ data.entry.frontmatter.title }}</h1>
<HollwareImage :entry="data.entry" field="img" />
<HollwareContent :entry="data.entry" :components="{ callout: Callout }" />
</article>
</template><HollwareContent>renders the entry from the document Hollware stored when it was written: no Markdown parser reaches the page.componentsmaps the components of your entries (::callout) to your own Vue components; anything else renders as its plain tag. Its images come with theirsrcset,sizes,widthandheight.<HollwareImage>renders the image a frontmatter field holds, such as a cover, with its alt, its size and the copies Hollware made of it. Any attribute you give wins:<HollwareImage :entry field="img" loading="lazy" sizes="50vw" />.
An entry that is not published answers a 404.
Lists, translations and the site
<script setup lang="ts">
const { data } = await useHollwareEntries('blog', { locale: 'en', limit: 10 })
</script>
<template>
<ul>
<li v-for="post in data?.entries" :key="post.id">
<HollwareImage :entry="post" field="img" loading="lazy" />
<NuxtLink :to="`/blog/${post.slug}/`">{{ post.frontmatter.title }}</NuxtLink>
</li>
</ul>
</template>| Composable | Gives |
|---|---|
useHollwareEntry(collection, locale, slug) | a published entry, with its document |
useHollwareEntries(collection, { locale, tag, limit, cursor }) | a page of published entries, newest first |
useHollwareTranslations(collection, group) | the entries of a translation group |
useHollwareSite() | the site: its locales and collections |
useHollware(event) (server) | the reader itself, for routes of your own |
The fields your collection has Hollware fill, such as a date or the reading time, come filled in the frontmatter (Configure your content).
Previews
Preview on the site, in the admin, opens the entry's page with a signed link for that one entry, valid for an hour. The module exchanges the link for an HttpOnly cookie, reads the latest revision of the entry, a draft included, and keeps nothing it answers. It needs the site's url in the admin, under Site.
Cache
hollware.cache: 'purge' keeps the pages of your site in Workers Cache and lets Hollware purge them, by tag, the moment you publish. See Caching.
Every page carries <meta name="generator" content="Hollware">; hollware.generator: false leaves it out.
A whole site
examples/nuxt-blog in the repository is a Nuxt blog on a Worker that reads the playground over a service binding, previews included.