Skip to content

Hugo migration - #406

Merged
kristin-kronstain-brown merged 51 commits into
mainfrom
kkb-hugo-docs-migration
Aug 5, 2026
Merged

Hugo migration#406
kristin-kronstain-brown merged 51 commits into
mainfrom
kkb-hugo-docs-migration

Conversation

@kristin-kronstain-brown

@kristin-kronstain-brown kristin-kronstain-brown commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Migrate docs to Hugo, build marketing + docs together

Summary

Migrates the kagent/kmcp documentation from Next.js MDX to a Hugo + Hextra + docs-theme-extras site, and wires it into the existing Next.js marketing app so both build and deploy as one Cloudflare Worker, one origin. The docs are served as static assets under /docs/*; the marketing site (home, blog, tools, agents, community, enterprise) stays on Next.js. Also unifies the top navbar so the marketing and docs pages look consistent.

Architecture

  • Monorepo layout. The Hugo docs site lives in docs-site/, alongside the Next.js app. The subdirectory sidesteps the package.json/go.mod collision that previously required a separate branch.
  • Docs served under /docs. Hugo's baseURL carries the /docs prefix and content lives at content/<product>/, so Hugo emits a self-contained tree (pages + css/js/images/favicons) that drops into the worker's static assets with no collisions against the marketing site's /images, sitemap.xml, etc.
  • Combined build via make. make build builds the Hugo docs, injects the output into public/docs/ (preserving tracked assets like versions/), then builds the opennextjs worker. Cloudflare Workers Assets serve /docs/* (static Hugo) before the worker runs, so the marketing worker handles everything else. Verified end-to-end with wrangler dev.

What's included

Docs site (docs-site/)

  • Full Hugo site: hugo.yaml, layouts, assets, content/kagent/** and content/kmcp/** (234 pages), Tailwind/PostCSS pipeline.
  • Project overrides: sidebar rooted per-product via .FirstSection; navbar-link.html for a Docs dropdown (kagent/kMCP with product icons) and uniform link styling; logo links to the marketing home (/).

Converter (scripts/mdx-to-hugo.mjs)

  • Idempotent MDX→Hugo converter (run via make gen-docs). Handles frontmatter merge, component→shortcode mapping (Tabs, Aside, FeatureGrid, Mermaid, QuickLink), version placeholders, link rewrites, and unwraps the 'use client' React-component wrapper (kmcp landing).

Build tooling

  • Root Makefile (build-docs, inject-docs, build-web, build, preview, deploy, serve-docs, gen-docs, clean). preview builds docs with a localhost baseURL so internal links stay local.
  • .gitignore updated for docs build artifacts and injected public/docs.

Navbar unification

  • Rewrote src/components/navbar.tsx to mirror the Hextra docs nav (order, uniform gray links, Docs dropdown with icons, GitHub icon, search, borderless theme toggle) in light and dark mode.
  • Decoupled /tools and /agents from the old docs layout (removed their layout.tsx) so they render as standalone marketing pages.

Fixes

  • Dropdown spacing/alignment, logo light/dark switch, and navbar dark-mode background handled in custom.css (Hextra's prebuilt CSS omits some hx: utilities).
  • Fixed a real source bug in the release-notes MDX (new-svc-tab panel id).

Editing the docs

docs-site/content/ is the source of truth — author docs there directly; the converter is only for re-migrating from the legacy src/app/docs MDX, not the normal workflow.

  • Edit / add pages: docs-site/content/kagent/** and docs-site/content/kmcp/** (Markdown with Hugo frontmatter). A leaf page is <name>.md; a section with children is a folder with _index.md. Ordering is weight in frontmatter; the sidebar and section cards are generated automatically.
  • Shortcodes: use the docs-theme-extras/Hextra shortcodes natively ({{< tabs >}}, {{< callout >}}, {{< cards >}}, etc.).
  • Nav / dropdown / menu: edit docs-site/hugo.yaml (menu.main). Same-origin marketing links use params.localHref; docs products use url: /<product>.
  • Styling: put custom CSS in docs-site/assets/css/custom.css (don't rely on ad-hoc hx: Tailwind utilities — many aren't generated in this build).
  • Re-migrating from MDX (rare): make gen-docs regenerates docs-site/content from src/app/docs. Diff before committing so hand edits aren't lost.

Previewing locally

First-time setup (installs web + docs deps and Hugo modules):

make install

Marketing + docs together — the real combined site (builds everything, serves via wrangler dev) at http://localhost:3000:

make preview

This is where to confirm /docs/* routing, cross-links between marketing and docs, and the unified navbar.

Notes:

  • In make serve-web/next dev, /docs falls back to the old Next route (no Cloudflare asset layer locally); use make preview to see the real Hugo docs.
  • If a page looks stale or shows the old nav, check for a leftover wrangler dev (workerd) still bound to port 3000 from a prior make previewpkill -f wrangler and restart.

Follow-ups

  • Old src/app/docs kept (shadowed by the Hugo docs at the edge); removable later once generate-nav/check-links are trimmed.
  • CI preview (.github/workflows/preview.yaml) still runs npm run build:worker; needs Hugo/Go setup + make build to include docs in PR previews.

Testing

  • Hugo build clean (234 pages, no leaks), link check 474 links / 0 broken.
  • Combined make build green; docs bundled into worker assets.
  • wrangler dev confirmed / → Next, /docs/* → Hugo.
  • Navbar verified light + dark against the docs nav.

Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
author: kagent.dev
---

Welcome to kagent! Start here to understand what kagent is, how to install it, and how to contribute.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicates the description

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines +10 to +15
{{< cards >}}
{{< card link="/docs/kagent/introduction/what-is-kagent" title="What is kagent?" subtitle="Learn about the core concepts and capabilities of kagent." >}}
{{< card link="/docs/kagent/introduction/installation" title="Installation" subtitle="Follow our guide to set up kagent." >}}
{{< card link="https://github.com/kagent-dev/kagent/blob/main/README.md#roadmap" title="Feature Roadmap" subtitle="See what we're planning for the future." >}}
{{< card link="https://github.com/kagent-dev/kagent/blob/main/CONTRIBUTING.md" title="Contributing" subtitle="Find out how you can help improve kagent." >}}
{{< /cards >}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think cards on any _index.md file would need to be removed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

kristin-kronstain-brown and others added 26 commits July 13, 2026 17:00
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Values whose @default comment contains a Helm/Go template example
(e.g. extraObjects: {{ include "kagent.fullname" . }}) were emitted as
bare {{ ... }} in prose. Hugo renders these literally, but any MDX
consumer parses {{ ... }} as a JSX expression and fails with
"Could not parse expression with acorn".

Extend the placeholder-backticking step to wrap bare {{ ... }} templates
in inline code, leaving already-backticked spans untouched so they are
not double-wrapped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
The extraObjects @default example (regenerated on main via #416) contains
bare {{ ... }} templates in a table cell. The Next.js MDX compiler parses
{{ ... }} as a JSX expression, so next build failed with "Could not parse
expression with acorn" at page.mdx:145. Wrap the two bare templates in
inline code so MDX treats them literally. Verified with a full next build.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Run make gen-docs (mdx-to-hugo) after merging main's regenerated
api-ref/helm pages and escaping the bare Helm templates, so the Hugo
content under docs-site/content matches the MDX source.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
The link to the operational-considerations database section was missing
the /docs/kagent prefix (/operations/... -> resolved to a nonexistent
public/operations/...), failing the link checker. Use the same
/docs/kagent/... form as every other internal link, and regenerate the
Hugo content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>

# Conflicts:
#	public/sitemap.xml
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Conflict resolutions:

- .github/workflows/update-ref-docs.yaml: kept this branch's version.
  Main added MDX brace-escaping to the Helm generation step, but that step
  was rewritten here to emit Hugo markdown into docs-site/content, where
  bare {{ }} is not a shortcode delimiter. This branch already wraps bare
  Helm templates in inline code, so main's escaping is redundant.

- src/app/docs/kagent/resources/helm/page.mdx: kept main's version.
  Both sides fixed the same MDX build failure (bare {{ }} from values.yaml
  comments); main's generator-produced escaping supersedes the hand-fix in
  6a99d76 and keeps this file byte-identical to main.

Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Main's last three ref-doc regenerations landed only in the Next.js MDX
pages, which this branch no longer publishes, so the Hugo pages served at
/docs were missing the content. Regenerated both from the merged MDX with
scripts/mdx-to-hugo.mjs:

- api-ref.md: adds BedrockGuardrailConfig, Bedrock readTimeout/connectTimeout,
  OpenAIAPIFormat, isolateSessions, deploymentAnnotations, envFrom.
- helm.md: adds controller/ui affinity and topologySpreadConstraints rows.
  Brace escaping from main's MDX fix is undone and bare {{ }} re-wrapped in
  inline code, matching what update-ref-docs.yaml now generates for Hugo.

kmcp/reference/api-ref.md was already current. Verified additions only (no
removals) and confirmed in the built HTML.

Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
kristin-kronstain-brown and others added 2 commits August 5, 2026 09:59
Takes main's Next 16 migration (#433) over this branch's Next 15 hold.
Git auto-merged @next/mdx and @next/third-parties to ^16.3.0 (main's side)
while keeping next at ^15.5.21 (this branch's side) — a silent peer-dep
conflict. Resolved next to ^16.3.0 so the three move together.

Kept this branch's security hardening, which main does not have:
  - postcss floor ^8.5.23 (was ^8)
  - overrides: postcss ^8.5.23, sharp ^0.35.0

The sharp override still does work under Next 16: next@16.3.0 declares
sharp ^0.35.3, but main's lock also carries a vulnerable sharp@0.34.5.
With the override the tree resolves to a single sharp@0.35.3.

public/sitemap.xml conflict resolved to main's copy (generated at build).

Verified: npm ci (root + docs-site) exit 0; make build exit 0 on Next 16
Turbopack, 234 Hugo pages, OpenNext worker built; npm audit clean for
next, postcss, and sharp; docs-site/content hand edits byte-identical.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
…pgrade)

Takes main's #434: @opennextjs/cloudflare ^1.14.8 -> ^1.20.2 and
cloudflare/wrangler-action v3.14.1 -> v4 in both deploy workflows.

package.json and the workflows auto-merged cleanly. package-lock.json had
27 conflict hunks; rather than hand-merge a generated lockfile, it was
resolved to main's copy and regenerated with npm install so the merged
package.json (including this branch's overrides) is reconciled by npm.

Still the only divergence from main:
  - postcss floor ^8.5.23 (was ^8)
  - overrides: postcss ^8.5.23, sharp ^0.35.0

Verified: npm ci (root + docs-site) exit 0; make build exit 0 on Next 16
Turbopack, 234 Hugo pages, OpenNext worker built; docs-site/content hand
edits byte-identical; npm audit clean for next, postcss, sharp, and
fast-xml-parser (the former critical).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Kristin Brown <kristin.brown@solo.io>
@kristin-kronstain-brown
kristin-kronstain-brown merged commit a95069b into main Aug 5, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants