The Astro starter builds a static site from your project's content: the blog, the changelog, the help center with search, your pages, a read-only roadmap and the site widget. Every page is plain HTML, read from Kookee when the site is built, so any static host serves it, and a Kookee webhook can start a new build each time you publish. The code is on GitHub at kookee-dot-dev/starter-astro, under the MIT license. To see it first, open the live demo, which shows the content of a made-up invoicing app.
Deploy it
In your project, open API keys under Connect and click Create Key. Copy the key.
On the starter's GitHub page, click Deploy with Vercel, and paste the key when Vercel asks for
KOOKEE_API_KEY.Once the site is live, open Settings → Project in Kookee and add its address to the Allowed Origins card, such as
https://help.example.com. Once the list holds an address, browsers on any other site are refused with403 ORIGIN_NOT_ALLOWED, and so are help search, reactions, the helpful vote, the status page and the widget on your site if its address is missing. The build's own reads are not affected. Only owners and admins can change the list or add the webhook below.
The site now shows your project's name in the header and your published content on every page. Without a key, the build makes a short setup guide instead.
On another static host, set SITE_URL to the site's address and deploy the dist folder that npm run build writes; without SITE_URL, canonical addresses, the sitemap, the feeds and llms.txt point at http://localhost:4321.
On your own machine, run npm create astro@latest -- --template kookee-dot-dev/starter-astro, put the key in .env, add http://localhost to Allowed Origins (it covers every port), and run npm run dev.
What the site shows
Address | What it shows |
|---|---|
| The newest posts and changelog entries, and your help categories |
| Posts, 12 per page; a post with its table of contents and reactions |
| Changelog entries; an entry with reactions |
| Categories and search as you type; a category's articles; an article with its table of contents and the "Was this article helpful?" vote |
| Up to 100 open feedback posts, most voted first, by column, read-only |
| Your status page, once you turn it on: incidents, maintenance and each component's uptime over 90 days; an incident with its updates, with times in the visitor's zone |
| Your pages, such as |
It also writes sitemap.xml, robots.txt, llms.txt and an RSS feed for the blog and one for the changelog. Each post, changelog entry, help article and page takes its title, description, canonical address, Open Graph tags and JSON-LD from the entry and its SEO fields. Only the interactive parts load JavaScript.
The header has a "What's new" badge for your latest changelog entries, and a link to your hosted portal when it is on. Under the header, a pill shows the title of the newest announcement the visitor hasn't dismissed, however old. It opens a dialog that lists the ten newest, without the ones the visitor dismissed; a click on one shows it in full. The build reads them, so publishing or unpublishing one shows after the next build. Dismissals stay in the visitor's browser; to take an announcement down for everyone, unpublish it.
The site widget appears after you save its settings under Site widget → Customize and rebuild; from then on it loads its tabs and texts in the browser, so later changes to them show within about a minute. Set KOOKEE_ROADMAP to false to leave the roadmap out. To add your status page at /status, with a "Status" link in the header, set KOOKEE_STATUS to true and rebuild, once you have set the page up as Set up a status page describes. The status page reads Kookee in the visitor's browser when it opens and again every minute while its tab is visible, so a new incident shows without a build.
The site uses your project's default language only. A help article without a category has no address on this site and is left out, and so is a page whose slug is blog, changelog, help, roadmap or status, or a post or changelog entry whose slug is page. A page with the slug status is left out even while the status page is off.
Rebuild when you publish
In Vercel, open the project's Settings → Git → Deploy Hooks, create a hook for your production branch, and copy its address.
In Kookee, open Webhooks under Connect, click Add endpoint, paste the address, select the four entry events and click Add endpoint.
In the endpoint's menu, click Send test. A new deployment starts in Vercel.
Each publish, edit, unpublish or deletion of a blog post, page, help article, changelog entry or announcement, in any language, now starts a build, and so does a scheduled entry when it goes live. Translations do not show on this site, but each one still starts a build. When several arrive close together, Vercel cancels the running build and starts the newest, so one build finishes, though every build that started has already read entries with your key. Vercel takes at most 60 hook calls an hour per project, and on the Free plan Kookee sends 100 content events an hour across the account.
Renaming the project, a category or a tag, roadmap changes and the first save of the widget settings send no event; they show after the next build. Leave the incident and monitor events off this endpoint: the status page needs no build, and each of them would start one.
What it costs
A build reads every entry it publishes, one request each, plus the lists, one export of every entry and the project, all with your key. It spaces its requests to about three a second, which keeps it under the project's limit per minute and leaves room for your visitors, whose browsers share that limit when they search help, open the widget's Help tab or react. A site of 1,000 entries takes at least six minutes to build. All of these count toward the monthly API requests of the project owner's account, which all its projects share: 100,000 a month on Free, so a build of a 1,000-entry site uses about 1% of them. Rate limits, plans and error handling lists every plan. The widget's AI chat is not an API request: each answer uses one of the account's monthly AI answers. Status page reads in the browser count toward neither the monthly requests nor the project's limit per minute: they have a rate limit of their own, ten times that limit.
Each build also counts one view for every blog post, page and help article it reads, and visitors to the static pages count none, so view counts go up by one per build. A help article opened in the widget's reader counts a view each time, and help article views decide the most viewed articles in the widget and on your portal.
The key is in your pages' code, so anyone can copy it and spend your requests and AI answers with it. It reads what is published, adds reactions and votes, searches help, asks the assistant and sends widget feedback, and cannot touch drafts or change content. Allowed origins stop other sites' browsers, not scripts; API keys and security explains how to replace a key.
Continue reading
Send events to your site with webhooks: deploy hooks, events and limits.
Build a blog with the React components: the components the starter's blog pages use.
Caching strategies for Kookee content: how long to cache your content, and when to clear it.