+12








fcd7c979df
Co-authored-by: Artur <145776561+arturict@users.noreply.github.com> Co-authored-by: arturict <arturict@users.noreply.github.com> Co-authored-by: Thomas <thomas@ajnart.fr> Co-authored-by: Afonso Jorge Ramos <afonsojorgeramos@gmail.com> Co-authored-by: Danura30082 <danura30082+github@gmail.com> Co-authored-by: Kushie <122986913+kushiemoon-dev@users.noreply.github.com> Co-authored-by: ajnart <thomas@ajnart.fr> Co-authored-by: ajnart <thomas@ajnart.dev> Co-authored-by: chenjun <chenjun@foxmail.com> Co-authored-by: Wikibear <wikibear@users.noreply.github.com> Co-authored-by: Bergasha <bergasha@gmail.com> Co-authored-by: leafyelin <43306196+leafyelin@users.noreply.github.com> Co-authored-by: Lucas Araujo <lucas.lra@gmail.com> Co-authored-by: GreenMonito <86085570+GreenMonito@users.noreply.github.com> Co-authored-by: Nerdy-Technician <roffo@nerdy-technician.social> Co-authored-by: Jun <34545896+jcstrong@users.noreply.github.com> Co-authored-by: Edmond Abraham <54119952+gitedmond@users.noreply.github.com> Co-authored-by: thrawnx <tight.bulb9384@fastmail.com> Co-authored-by: Chris <58918656+nordada@users.noreply.github.com> Co-authored-by: yi111 <153097222+Yi-111-a@users.noreply.github.com> Co-authored-by: Yanis <naamaneyanis@gmail.com> Co-authored-by: Wikibear <me@sej.de> Co-authored-by: alessiottavo <93441886+alessiottavo@users.noreply.github.com>
169 lines
11 KiB
Markdown
169 lines
11 KiB
Markdown
# Homarr documentation (`@homarr/docs`)
|
|
|
|
The source for [homarr.dev](https://homarr.dev), built with Next.js and Fumadocs UI inside the Homarr monorepo.
|
|
|
|
## Develop
|
|
|
|
From the repository root:
|
|
|
|
```bash
|
|
pnpm dev:docs
|
|
```
|
|
|
|
The site runs on `http://127.0.0.1:3003`. To use a local Workshop API:
|
|
|
|
```bash
|
|
WORKSHOP_API_URL=http://127.0.0.1:8090 pnpm dev:docs
|
|
```
|
|
|
|
## Validate
|
|
|
|
```bash
|
|
pnpm --filter @homarr/docs typecheck
|
|
pnpm --filter @homarr/docs build
|
|
pnpm --filter @homarr/docs validate:links
|
|
pnpm --filter @homarr/docs verify:search
|
|
pnpm --filter @homarr/docs verify:seo
|
|
```
|
|
|
|
The static export is written to `out/`. The build validates docs pages and typed metadata for integrations and widgets
|
|
that declare a documentation slug. Set the slug to `null` when a page would add no useful information for advanced users.
|
|
CI enforces coverage alongside schema drift and export validation. The link check validates internal Markdown and MDX
|
|
links and rendered anchors against the export.
|
|
The search check exercises the exported index with title, heading, and body queries and verifies result destinations.
|
|
The SEO check validates canonical URLs, descriptions, social metadata, heading structure, and sitemap coverage in the
|
|
exported HTML. These tags are generated at build time; set `HOMARR_WEBSITE_URL` before building for a different origin.
|
|
|
|
## Preview the static export with PocketBase
|
|
|
|
After building the docs, run from the repository root:
|
|
|
|
```bash
|
|
sh apps/workshop/preview-docs.sh
|
|
```
|
|
|
|
Open `http://127.0.0.1:8093/docs/`. This starts an isolated PocketBase container with temporary local data and serves
|
|
the export directly, including search, Markdown, and the custom 404 page. Workshop browser requests use the configured
|
|
backend; a trailing `/api/` is removed because the PocketBase SDK appends its API paths. The preview does not copy or
|
|
migrate another database. Set `WORKSHOP_API_URL` to a remote PocketBase origin when testing against one;
|
|
`WORKSHOP_REMOTE_API_URL` can override the server-side metadata source independently. Direct item links then use that
|
|
source for titles and social metadata. Missing remote items return 404; an unavailable backend returns 503.
|
|
|
|
Verify public item pages without changing the remote database:
|
|
|
|
```bash
|
|
REMOTE_WORKSHOP_URL=https://workshop.example.com
|
|
WORKSHOP_TEST_URL=http://127.0.0.1:8093 WORKSHOP_REMOTE_API_URL="$REMOTE_WORKSHOP_URL" \
|
|
node apps/workshop/tests/remote-workshop.integration.mjs
|
|
```
|
|
|
|
Stop it with `docker stop homarr-docs-static-preview`. Rebuild and restart the preview after changing source files;
|
|
startup recreates the runtime configuration. `DOCS_PREVIEW_PORT`, `DOCS_PREVIEW_HOST`, and `DOCS_PREVIEW_NAME` override
|
|
the defaults. Set the host to this machine's Tailscale address to access it from your other devices.
|
|
|
|
## Write content
|
|
|
|
Documentation lives in `docs/`; project posts live in `blog/`. Navigation is controlled by the nearest `meta.json`.
|
|
Integration and widget folders pair typed `index.ts` metadata with `index.mdx` content.
|
|
|
|
Use standard Markdown and MDX. Shared components live in `src/components/`. Mermaid fences, tabs, callouts, zoomable
|
|
images, and syntax-highlighted code are supported by the Fumadocs pipeline.
|
|
|
|
Update docs in the same pull request only when a smart, advanced user cannot infer the changed behavior from the UI or
|
|
generated API schema. Routine or self-explanatory changes need no docs update. See the
|
|
[documentation-sync skill](../../.agents/skills/documentation-sync/SKILL.md) for target paths.
|
|
|
|
## Published formats
|
|
|
|
- `/docs` — searchable documentation with typed navigation
|
|
- `/api-reference` — interactive reference generated from the OpenAPI schema
|
|
- `/llms.txt` — compact documentation and blog index for agents
|
|
- `/llms-full.txt` — complete processed Markdown corpus
|
|
- `/llms.mdx/docs/.../content.md` — raw Markdown for each docs page
|
|
- `/llms.mdx/blog/.../content.md` — raw Markdown for each blog post
|
|
- `/llms.mdx/api-reference/.../content.md` — operation parameters, bodies, responses, and authentication
|
|
- `/blog/rss.xml` — RSS feed for project posts
|
|
- `/search?q=...` — opens documentation search with the supplied query, including existing Homarr search-engine links
|
|
|
|
Every docs page and blog post includes copy-Markdown and view-source actions. Search is generated at build time and
|
|
runs locally in the browser; it does not depend on an external crawler. Markdown exports and search resolve
|
|
integration credentials and widget defaults from the same typed metadata used by the pages.
|
|
The search dialog and its client-side engine load when search is first opened. Fumadocs caches the downloaded index
|
|
for subsequent queries. The docs index, individual Markdown pages, and full corpus share the `llms()` renderer.
|
|
API operations are indexed alongside docs and exported as Markdown from the same OpenAPI schema. The reference uses
|
|
Fumadocs with Scalar: select an instance URL and API key, then explicitly send a request. Authentication is not
|
|
persisted in local storage. Browser access requires the documented REST CORS configuration.
|
|
|
|
The Custom JSX guide includes a lazily loaded, editable example using the application renderer and real component
|
|
registry. Its bindings work locally; configured widget queries and actions do not run.
|
|
|
|
The getting-started overview and complete Custom JSX component catalog are also included, with property types,
|
|
binding contracts, and blocked capabilities taken from the published catalog JSON.
|
|
|
|
Published Docusaurus `/docs/category/...` addresses remain available as static compatibility pages. They forward to
|
|
the corresponding overview or developer setup guide, preserving query strings and anchors, and provide a direct
|
|
link when JavaScript is disabled. Their canonical metadata points to the destination; compatibility pages are
|
|
excluded from search and the sitemap.
|
|
|
|
## Fumadocs upgrade notes
|
|
|
|
The September 2026 update moves Core/UI from 16.15.4 to 16.15.12, MDX from 15.4.0 to 15.4.3, and OpenAPI from
|
|
11.3.5 to 12.0.1. Review the upstream [Core](https://github.com/fuma-nama/fumadocs/blob/dev/packages/core/CHANGELOG.md),
|
|
[UI](https://github.com/fuma-nama/fumadocs/blob/dev/packages/radix-ui/CHANGELOG.md),
|
|
[MDX](https://github.com/fuma-nama/fumadocs/blob/dev/packages/mdx/CHANGELOG.md), and
|
|
[OpenAPI](https://github.com/fuma-nama/fumadocs/blob/dev/packages/openapi/CHANGELOG.md) changelogs when upgrading.
|
|
|
|
- Core/UI and MDX now declare side effects for better tree shaking. UI also fixes tabs reverting to the URL hash.
|
|
- Core's `llms({ renderPage })` API provides the shared `index()`, `page()`, and `full()` exports.
|
|
- OpenAPI 12 replaces several custom renderer options and hooks. This site uses `createOpenAPIPage()` and
|
|
`getOpenAPIPageProps()` without those removed overrides; the built-in renderer retains all request languages.
|
|
The Scalar adapter receives an equivalent nonrecursive union for unconstrained JSON values to avoid recursive
|
|
schema expansion during rendering. The generated public OpenAPI document remains unchanged.
|
|
- MDX 15.4.3 fixes duplicate compilation output when its experimental build cache is enabled. We leave that cache
|
|
disabled: its current key checks source content without accounting for all compiler configuration changes.
|
|
- The existing macro collections, processed-Markdown component adapters, and static search remain supported.
|
|
Typed version roots and server-side MCP tools are available upstream but are not needed by this static site.
|
|
|
|
## Kapa AI
|
|
|
|
The compact Homarr mascot in the bottom-right opens **Ask AI**. It slowly spins when idle and gives a subtle claw movement and wink on hover. Animation respects reduced motion.
|
|
|
|
The launcher uses Homarr's existing public Kapa Website ID. The root layout loads the widget once across
|
|
client-side navigation and follows the docs light or dark theme. **Search** and `Ctrl+K` / `Cmd+K` always use Fumadocs search, including when Kapa is unavailable.
|
|
|
|
Set `KAPA_WEBSITE_ID` at build time to use a different Kapa Website Widget integration. An explicitly empty value
|
|
disables the widget, for example `KAPA_WEBSITE_ID= pnpm --filter @homarr/docs build`. This is a public integration ID
|
|
included in exported pages, not a Kapa API key. Rebuild the static export after changing it.
|
|
|
|
In the Kapa dashboard, confirm the integration is live and enable the production and preview domains. Restoring the
|
|
script does not verify that the historical integration is still active. Follow the
|
|
[Kapa widget setup](https://docs.kapa.ai/integrations/website-widget/quickstart) for domain restrictions and CSP settings.
|
|
|
|
After changing the documentation structure, review the Website Crawl source in Kapa: use the deployed `/docs` URL as
|
|
the start URL and preview `main` as the content selector. Replace any old Docusaurus-specific selector and check that
|
|
titles, headings, code samples, and integration details appear in the extracted Markdown. Docs are exported as HTML;
|
|
the site also publishes `/sitemap.xml` and permits crawling in `/robots.txt`. The `/llms.txt` exports do not configure
|
|
Kapa ingestion automatically. See [Kapa source setup](https://docs.kapa.ai/getting-started/index-your-first-source).
|
|
|
|
Before publishing, check that Ask AI opens after navigating between pages, ask a documentation question, and verify
|
|
its citations point to the current docs. In a separate check, block `widget.kapa.ai` and confirm search still works.
|
|
|
|
## Release verification
|
|
|
|
The production image compiles the docs itself; it does not depend on a host `out/` directory.
|
|
Build-time `HOMARR_WEBSITE_URL` controls canonical metadata. Runtime URL overrides configure Workshop connections
|
|
but do not rewrite already-exported canonical URLs.
|
|
|
|
PostHog records SPA pageviews, installation clicks, searches with no results (including the search query), and Workshop
|
|
content downloads and submission starts/completions through `hog.homarr.dev`. Downloads include JSON files and
|
|
successful JSON/CSS clipboard copies. All events carry `site` and `source_path`. Autocapture, page-leave events, and
|
|
session replay are disabled; tracked URL query strings and fragments are removed. Localhost and `?analytics_test`
|
|
traffic carries `verification=true`; exclude it from production reports.
|
|
|
|
Carbon loads one visible placement after the desktop TOC, below API examples, or below content on other layouts.
|
|
The homepage is excluded at every viewport size. Navigation reloads the ad script; resizing changes placement only when crossing its breakpoint. Ad blockers
|
|
or no-fill responses must not prevent content, navigation, or search from working.
|
|
|
|
To preview Carbon locally, start docs with `NEXT_PUBLIC_ENABLE_CARBON_ADS=true pnpm dev:docs`. Production builds
|
|
enable ads automatically. When the TOC collapses into a toggle, the ad appears below the content before “Edit this page”.
|