Skip to content

feat(modules): host module docs under their module page - #2550

Draft
atinux wants to merge 11 commits into
mainfrom
feat/module-docs
Draft

atinux wants to merge 11 commits into
mainfrom
feat/module-docs

Conversation

@atinux

@atinux atinux commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Opened by an AI agent (Amp) on behalf of @atinux, as a draft to iterate on.

Hosts a module's docs under its module page, the same way the nuxt/cli command reference is mounted under /docs/<version>/api/commands. It starts with @nuxt/icon, whose docs come from nuxt/icon#554 (for nuxt/icon#466).

  • Opt-in per module: shared/utils/module-docs.ts maps a registry module name to a repository, branch and contentDir. Only modules listed there get docs; every other module page is unchanged.
  • Content instance: each listed module gets a module:<name> instance mounted at /modules/<name>. The push webhook and ref refresh pick it up from CONTENT_INSTANCE_KEYS.
  • Module page: modules/[slug].vue moves to modules/[slug]/[...path].vue.
    • /modules/<name> renders the docs index.md instead of the README, so a docs source must have one. /api/v1/modules/<name> skips the README for these modules.
    • The module, the docs navigation and the docs page are fetched in parallel. The navigation is fetched once per module, since the page instance is kept across its docs pages.
    • Docs pages get a navigation aside, a breadcrumb that follows the docs tree, a table of contents, an edit link and previous/next links.
    • Only the module page shows the module header (stats, maintainers, install). Docs pages open on their breadcrumb, with the module icon next to its name.
    • On mobile, the asides become drawers.
  • SEO: docs pages get their own title, description and canonical URL. Their OG image shows the docs trail as headline (@nuxt/icon > Guide) and the page title. They also get TechArticle and BreadcrumbList structured data, like /docs pages, and are listed in the sitemap.
  • Bundle size: the docs-only UI lives in ModuleDocs* components loaded with Lazy*, so module pages without docs don't load it.
  • AI agents: docs pages negotiate markdown and link their /raw/**.md twin like /docs pages. They are listed in /sitemap.md, /llms.txt (one section per module) and /llms-full.txt.
  • Refactor: cliDocs() is now repoImages(repo, branch), shared by the CLI and module docs.

Before merging:

Not covered yet: search, the build snapshot and /pull previews for module docs.

pnpm lint and the unit tests pass. The app, server and shared type checks pass. The pages were checked in a dev server at desktop and mobile widths, using a local nuxt/icon checkout (NUXT_ICON_PATH).

ampagent and others added 2 commits October 25, 2026 09:44
Rename `cliDocs(version)` to `repoImages(repo, branch)` so other
sources read from their own repository can resolve root-relative images.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
Modules with a docs source configured in `shared/utils/module-docs.ts`
get their own content instance (`module:<name>`), mounted at
`/modules/<name>`. The module page renders the docs `index.md` instead
of the README, with a docs navigation aside (drawers on mobile), and
serves every docs page at `/modules/<name>/...`.

Starts with @nuxt/icon (nuxt/icon#466).

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
@vercel

vercel Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
nuxt Ready Ready Preview Oct 25, 2026 6:30pm UTC

Request Review

@nuxt-com-bundle-report

nuxt-com-bundle-report Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Production bundle

Comparing f8211427 with 048bb558. Compressed sizes are calculated from the emitted production assets.

Initial page load

Page Base JS (Brotli) PR JS (Brotli) Δ JS Δ CSS Δ files
/ 550.1 KiB 550.4 KiB +305 B (+0.1%) -48 B (-0.1%) +1
/docs/4.x/getting-started/introduction 611.7 KiB 612.6 KiB +923 B (+0.1%) -48 B (-0.1%) +4
/modules/ui 542.5 KiB 544.7 KiB +2.3 KiB (+0.4%) -48 B (-0.1%) +2
/updates 449.1 KiB 449.5 KiB +365 B (+0.1%) -48 B (-0.1%) +1
/blog/v4-6 572.2 KiB 573.0 KiB +769 B (+0.1%) -48 B (-0.1%) +3
/templates 430.0 KiB 430.4 KiB +361 B (+0.1%) -48 B (-0.1%) +1

Entry script, modulepreload chunks and stylesheets referenced by the prerendered HTML. Lazy and prefetched chunks are excluded.

All client assets

Metric Base (Brotli) PR (Brotli) Δ Brotli Δ gzip
Client JavaScript 2.19 MiB 2.19 MiB +4.9 KiB (+0.2%) +5.2 KiB (+0.2%)
Client CSS 33.8 KiB 33.8 KiB -48 B (-0.1%) +88 B (+0.2%)
Other client assets 339.3 KiB 339.3 KiB -4 B (-0.0%) -2 B (-0.0%)
Total client assets 2.55 MiB 2.56 MiB +4.8 KiB (+0.2%) +5.3 KiB (+0.2%)

Largest module increases

Module Base (Brotli) PR (Brotli) Δ Brotli
/app/pages/modules/[slug]/[...path].vue?vue&type=script&setup=true&lang.ts 0 B 4.7 KiB +4.7 KiB
/app/components/module/ModuleDocsMobileBar.vue?vue&type=script&setup=true&lang.ts 0 B 967 B +967 B
/app/components/module/ModuleDocsPage.vue?vue&type=script&setup=true&lang.ts 0 B 711 B +711 B
virtual:nuxt-workers.mjs?source=%2Fhome%2Frunner%2Fwork%2Fnuxt.com%2Fnuxt.com%2Fapp%2Fworkers%2Fsearch.ts 0 B 408 B +408 B
/app/components/module/ModuleDocsAside.vue?vue&type=script&setup=true&lang.ts 0 B 367 B +367 B
node_modules/@nuxt/scripts/dist/runtime/components/async-data-chunk-31.js 0 B 255 B +255 B
/app/composables/async-data-chunk-24.js 0 B 248 B +248 B
/shared/utils/module-docs.ts 0 B 241 B +241 B
/app/pages/nuxters/async-data-chunk-8.js 0 B 237 B +237 B
/app/pages/modules/[slug]/async-data-chunk-9.js 0 B 212 B +212 B

Module values come from Nuxt’s analyzer and are attribution estimates. This workflow is currently report-only.

Workflow run

ampagent and others added 2 commits October 25, 2026 11:06
Drawers, the docs navigation, surround links and the docs image component
are only rendered for modules with docs; `Lazy*` keeps them out of the
initial bundle of every other module page.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
- OG image: the docs trail as headline (`@nuxt/icon > Guide`), the page title as title
- TechArticle and BreadcrumbList structured data, like `/docs` pages
- List module docs pages in the sitemap

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
ampagent and others added 2 commits October 25, 2026 11:27
- Pass the docs page `useAsyncData` key as a `computed`: the build's async-data
  handler extraction took the getter key for a handler, so production pages
  failed to hydrate with NUXT_E3008
- Fetch the module, the docs navigation and the docs page in parallel, the
  navigation once per module
- Skip the README in `/api/v1/modules/<name>` for modules with docs: it was
  shipped in every docs page payload (~140 KB)
- Lazy-load the docs UI through `ModuleDocs*` components rather than lazy
  library components, which split shared chunks on every page
- Keep a single h1 on docs pages: the page title, not the module name

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
Module docs pages negotiate markdown and link their `/raw/**.md` twin like
`/docs` pages, and are listed in `/sitemap.md`, `/llms.txt` and
`/llms-full.txt`.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
`modules:v5` entries still carry the README of modules with docs.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
Docs pages open on their breadcrumb, where the module icon marks the module,
so moving between them does not land below a tall header.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
For modules with docs, the Menu / On this page bar sits right under the
site header, and docs page titles follow their breadcrumb closely.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
Both wrap on narrow screens. Below `sm` the stats show their icon and number,
with `downloads`/`stars` kept for screen readers and the tooltips.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>
The score was copied into the module by a watcher on the shared health map.
Arriving from `/modules`, that map is already loaded, so the watcher never
fired. Read it from the map with a computed instead.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1721c-4512-7150-9905-efce9f4b7f68
Co-authored-by: Sébastien Chopin <atinux@gmail.com>

This branch was successfully deployed

1 active deployment
Preview — 048bb558 Deployed Oct 25, 2026 by vercel[bot]
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.

2 participants