Custom Website
Add Knoku to a custom documentation site, static site generator, or framework that does not have a dedicated guide.
Before you start
The widget only works once your project exists and your docs are indexed:
- Create a project and add your site’s domain as the allowed domain. See Widget installation.
- Sync your docs with
knoku initandknoku pushso answers come from your own content.
Add the widget
Put the widget script in the global HTML template, layout, app shell, or base page that renders every documentation page:
<script
async
src="https://cdn.knoku.com/widget.js"
data-project-id="YOUR_PROJECT_ID"
></script>Common locations:
| Site type | Place the script in |
|---|---|
| Static HTML | shared <head> or footer partial |
| Next.js | root layout or _app with next/script |
| Astro | base layout component |
| Eleventy | base Nunjucks/Liquid layout |
| Hugo | base template or partial included by every page |
| Jekyll | _layouts/default.html or an included partial |
The script can live in <head> or near the end of <body>. Use async so it does not block rendering.
Configure the widget
Add optional data-* attributes to the same script:
<script
async
src="https://cdn.knoku.com/widget.js"
data-project-id="YOUR_PROJECT_ID"
data-greeting="How can I help?"
data-launcher-text="Need help?"
data-suggested-questions="Get started|rocket,API reference|code,Pricing|card"
></script>Full list: Attributes reference. For per-slot visual overrides (data-panel-header-background-color, etc.) see Component Styles.
Add an Ask AI button
Add any button or link on your page and point data-open-selector at it:
<button id="ask-ai" type="button">Ask AI</button>
<script
async
src="https://cdn.knoku.com/widget.js"
data-project-id="YOUR_PROJECT_ID"
data-open-selector="#ask-ai"
></script>To use only your button and hide the floating launcher:
data-launcher-hidden="true"The widget watches the DOM, so this also works when your framework renders the button after page load. See Add an AI button to your header.
Sync docs manually
If no framework adapter is detected, knoku init uses the current directory as the docs root.
Most custom sites should set KNOKU_DOCS_DIR explicitly in .knoku/.env:
KNOKU_DOCS_DIR=./docsThen push:
npx @knoku/cli@latest pushKnoku uploads .md, .mdx, and .rst files. Other formats are ignored.
URL mapping
Without a framework adapter, citation URLs are generated by stripping the file extension and any /index suffix:
| File | Default citation URL |
|---|---|
index.md | / |
getting-started.md | /getting-started |
guides/install.mdx | /guides/install |
api/auth/index.md | /api/auth |
If your site is served under a subpath, set KNOKU_URL_BASE:
KNOKU_URL_BASE=/docsThen guides/install.mdx maps to /docs/guides/install.
For a one-off page, add url: frontmatter:
---
url: /guides/install/
---
# InstallFrontmatter url: has the highest priority. See CLI configuration.
CI sync
Run push whenever docs change:
- name: Push docs to Knoku
env:
KNOKU_API_KEY: ${{ secrets.KNOKU_API_KEY }}
KNOKU_PROJECT_ID: ${{ secrets.KNOKU_PROJECT_ID }}
KNOKU_API_URL: https://api.knoku.com
KNOKU_DOCS_DIR: ./docs
run: npx @knoku/cli@latest pushVerify
npx @knoku/cli@latest doctorThen open your deployed docs site and check that:
https://cdn.knoku.com/widget.jsloadshttps://api.knoku.com/api/v1/config/{projectId}returns200- the widget appears on every docs page
- answers cite URLs that exist on your site
If the config request returns 403, add the exact production host as the project’s allowed domain.