Skip to content

feat: add docs for 5.x branch#2192

Merged
danielroe merged 8 commits intomainfrom
feat/5.x
Mar 2, 2026
Merged

feat: add docs for 5.x branch#2192
danielroe merged 8 commits intomainfrom
feat/5.x

Conversation

@danielroe
Copy link
Copy Markdown
Member

🔗 Linked issue

📚 Description

In preparation for the upcoming release of Nuxt5, we've already split out a 4.x branch from main, and we want the Nuxt.com deploy to come from this 4.x branch

we still also want users to be able, if needed, to preview the docs for 5.x.

@danielroe danielroe requested a review from atinux as a code owner March 2, 2026 11:14
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Mar 2, 2026

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

Project Deployment Actions Updated (UTC)
nuxt Ready Ready Preview, Comment Mar 2, 2026 2:55pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 2, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Nuxt docs v5 support and updates v4 branch references across the project. Introduces docsV5 sources, examplesV5, a docsv5 collection and content.config entries. Extends useDocsVersion with v5 (new Version entry, tag mapping, useDocsTags) and changes default/version resolution to prefer 5.x then 4.x then 3.x. Updates server endpoints (navigation, search, sitemap, MCP tools) and client routing/middleware to recognize /docs/5.x. Simplifies versionFiles filtering in app.vue and error.vue. Adjusts admin edit URL to point to branch 4.x. Multiple TODO/comment additions for v5.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding documentation support for the 5.x branch in preparation for the Nuxt 5 release.
Description check ✅ Passed The description is directly related to the changeset, explaining the motivation (Nuxt 5 release preparation), the context (4.x branch split from main), and the requirement (support 5.x docs preview).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/5.x

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/composables/useDocsVersion.ts (1)

3-10: Add collection: 'docsv5' to the v5 version object for type consistency.

The collection property is optional and currently unused in app code, so v5 functions without it. However, for consistency with v3 and v4—and to support any future code that relies on this property—add collection: 'docsv5' to the v5 object and update the type union to include 'docsv5'. The collection is already defined in content.config.ts.

Suggested adjustment
 interface Version {
   label: string
   shortTag: 'v5' | 'v4' | 'v3' | 'v2'
   branch: string
   tagColor: BadgeProps['color']
   path: string
-  collection?: 'docsv3' | 'docsv4'
+  collection?: 'docsv3' | 'docsv4' | 'docsv5'
 }
   {
     label: 'Version 5',
     shortTag: 'v5',
     branch: 'main',
     tagColor: 'warning',
-    path: '/docs/5.x'
+    path: '/docs/5.x',
+    collection: 'docsv5'
   },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/composables/useDocsVersion.ts` around lines 3 - 10, The Version interface
is missing 'docsv5' in its collection union and the v5 version object lacks
collection: 'docsv5', causing inconsistency; update the Version type union to
include 'docsv5' and add collection: 'docsv5' to the v5 version object (look for
the Version interface definition and the v5 object where shortTag: 'v5' is used)
so v5 matches v3/v4 and future code relying on collection will work.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/AdminDashboard.vue`:
- Line 501: The GitHub edit URL hardcodes branch "4.x" — derive the branch from
selectedPage.lastFeedback.stem instead; add a small computed property or method
(e.g., editBranch or computeEditUrl) that extracts the version with a regex like
/docs\/(\d+\.x)/ and falls back to a sensible default (e.g., 'main' or strip
docs/ prefix) and then use that variable in the template
(:to="`https://github.com/nuxt/nuxt/edit/${editBranch}/${selectedPage.lastFeedback.stem.replace(/docs\/\d\.x/,
'docs')}.md`" or return the full URL from computeEditUrl), so the link uses the
page's actual version instead of always "4.x".

In `@content.config.ts`:
- Around line 207-210: The docsv5 collection is incorrectly referencing
examplesV4Source, causing v4 example routes to be included; update the docsv5
defineCollection to use examplesV5Source instead of examplesV4Source (keep
docsV5Source as the other source) so that the docsv5 collection only pulls v5
examples; locate the docsv5 defineCollection block and replace the
examplesV4Source identifier with examplesV5Source.

---

Nitpick comments:
In `@app/composables/useDocsVersion.ts`:
- Around line 3-10: The Version interface is missing 'docsv5' in its collection
union and the v5 version object lacks collection: 'docsv5', causing
inconsistency; update the Version type union to include 'docsv5' and add
collection: 'docsv5' to the v5 version object (look for the Version interface
definition and the v5 object where shortTag: 'v5' is used) so v5 matches v3/v4
and future code relying on collection will work.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4932208 and fd52909.

📒 Files selected for processing (3)
  • app/components/AdminDashboard.vue
  • app/composables/useDocsVersion.ts
  • content.config.ts

variant="ghost"
color="neutral"
:to="`https://github.com/nuxt/nuxt/edit/main/${selectedPage.lastFeedback.stem.replace(/docs\/\d\.x/, 'docs')}.md`"
:to="`https://github.com/nuxt/nuxt/edit/4.x/${selectedPage.lastFeedback.stem.replace(/docs\/\d\.x/, 'docs')}.md`"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use a version-aware branch for the edit URL.

Line 501 hardcodes 4.x, so feedback from /docs/5.x can generate a wrong GitHub edit link. Pick branch from the page stem/path instead of forcing 4.x.

Proposed fix
<script setup lang="ts">
@@
+function getDocsBranchFromStem(stem?: string) {
+  if (stem?.startsWith('docs/5.x/')) return 'main'
+  if (stem?.startsWith('docs/3.x/')) return '3.x'
+  return '4.x'
+}
</script>
-:to="`https://github.com/nuxt/nuxt/edit/4.x/${selectedPage.lastFeedback.stem.replace(/docs\/\d\.x/, 'docs')}.md`"
+:to="`https://github.com/nuxt/nuxt/edit/${getDocsBranchFromStem(selectedPage.lastFeedback.stem)}/${selectedPage.lastFeedback.stem.replace(/docs\/\d\.x/, 'docs')}.md`"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/AdminDashboard.vue` at line 501, The GitHub edit URL hardcodes
branch "4.x" — derive the branch from selectedPage.lastFeedback.stem instead;
add a small computed property or method (e.g., editBranch or computeEditUrl)
that extracts the version with a regex like /docs\/(\d+\.x)/ and falls back to a
sensible default (e.g., 'main' or strip docs/ prefix) and then use that variable
in the template
(:to="`https://github.com/nuxt/nuxt/edit/${editBranch}/${selectedPage.lastFeedback.stem.replace(/docs\/\d\.x/,
'docs')}.md`" or return the full URL from computeEditUrl), so the link uses the
page's actual version instead of always "4.x".

Comment thread content.config.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/mcp/tools/list-documentation-pages.ts (1)

45-59: ⚠️ Potential issue | 🟡 Minor

version: "all" currently excludes 5.x docs.

Now that 5.x is a supported input, returning only v3+v4 for "all" makes the result incomplete.

💡 Suggested fix
-      // TODO: include docsv5 in 'all' when Nuxt 5 is released
-      const docsV3 = await queryCollection(event, 'docsv3')
-        .select('title', 'path', 'description')
-        .all()
-
-      const docsV4 = await queryCollection(event, 'docsv4')
-        .select('title', 'path', 'description')
-        .all()
-
-      if (!docsV3 || !docsV4) {
+      const [docsV3, docsV4, docsV5] = await Promise.all([
+        queryCollection(event, 'docsv3')
+          .select('title', 'path', 'description')
+          .all(),
+        queryCollection(event, 'docsv4')
+          .select('title', 'path', 'description')
+          .all(),
+        queryCollection(event, 'docsv5')
+          .select('title', 'path', 'description')
+          .all()
+      ])
+
+      if (!docsV3 || !docsV4 || !docsV5) {
         return errorResult('Documentation pages collection not found')
       }
-
-      allDocs = [...docsV3, ...docsV4]
+      allDocs = [...docsV3, ...docsV4, ...docsV5]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/mcp/tools/list-documentation-pages.ts` around lines 45 - 59, The "all"
branch currently only queries docsv3 and docsv4, omitting docsv5; update the
logic in the function that sets allDocs (look for variables docsV3, docsV4,
allDocs and the calls to queryCollection) to also query docsv5 via
queryCollection(event, 'docsv5').select('title','path','description').all(),
include docsV5 in the existence check alongside docsV3/docsV4, and add docsV5 to
the spread when building allDocs so "all" returns v3+v4+v5 (also remove or
update the TODO about Nuxt 5 if present).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/composables/useDocsVersion.ts`:
- Around line 47-50: The dist-tag map in useDocsVersion.ts currently lists
non-existent npm tags v5:'5x' and v4:'4x' which causes the code that reads
distTags (used around the fallback at line 58) to silently resolve to
distTags.latest; update the dist-tag mapping (the map object in useDocsVersion)
to use actual npm tags (e.g., map the v5 entry to 'next' and v4 to 'latest' or
other real dist-tags your npm registry uses) and change the resolution logic
that looks up distTags['5x'] / distTags['4x'] to explicitly check for existence
and, if missing, choose the correct explicit fallback (e.g., distTags.next for
v5) and log or throw a clear warning instead of silently using distTags.latest.

In `@server/api/navigation.json.get.ts`:
- Around line 5-10: queryCollectionNavigation calls may yield undefined for
branches like docsv5 because of data[0]?.children, causing sparse/null entries
to remain after .flat(); fix by normalizing each promise result to an array
(e.g. replace .then(data => data[0]?.children) with .then(data =>
data[0]?.children ?? []) or, alternatively, after Promise.all use .then(results
=> results.flat().filter(Boolean)) so the exported navigation from this module
has no null/undefined entries; update the code referencing
queryCollectionNavigation and the final .then handler accordingly.

---

Outside diff comments:
In `@server/mcp/tools/list-documentation-pages.ts`:
- Around line 45-59: The "all" branch currently only queries docsv3 and docsv4,
omitting docsv5; update the logic in the function that sets allDocs (look for
variables docsV3, docsV4, allDocs and the calls to queryCollection) to also
query docsv5 via queryCollection(event,
'docsv5').select('title','path','description').all(), include docsV5 in the
existence check alongside docsV3/docsV4, and add docsV5 to the spread when
building allDocs so "all" returns v3+v4+v5 (also remove or update the TODO about
Nuxt 5 if present).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd52909 and 2a562f5.

📒 Files selected for processing (14)
  • app/app.vue
  • app/composables/useDocsVersion.ts
  • app/error.vue
  • content.config.ts
  • nuxt.config.ts
  • public/robots.txt
  • server/api/navigation.json.get.ts
  • server/api/search.json.get.ts
  • server/mcp/prompts/find-documentation-for-topic.ts
  • server/mcp/resources/nuxt-documentation-pages.ts
  • server/mcp/tools/get-documentation-page.ts
  • server/mcp/tools/get-getting-started-guide.ts
  • server/mcp/tools/list-documentation-pages.ts
  • server/routes/sitemap.xml.ts
✅ Files skipped from review due to trivial changes (3)
  • server/mcp/resources/nuxt-documentation-pages.ts
  • server/mcp/tools/get-getting-started-guide.ts
  • server/mcp/prompts/find-documentation-for-topic.ts

Comment on lines +47 to 50
v5: '5x',
v4: '4x',
v3: '3x',
v2: '2x'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Verify available dist-tags for nuxt and whether 5x/4x exist.
curl -s https://registry.npmjs.org/nuxt \
  | jq -r '."dist-tags" | to_entries[] | "\(.key)=\(.value)"' | sort

echo "---"

# Explicit boolean checks for expected keys.
curl -s https://registry.npmjs.org/nuxt \
  | jq -r '."dist-tags" | {has_5x: has("5x"), has_4x: has("4x"), has_latest: has("latest"), keys: keys}'

Repository: nuxt/nuxt.com

Length of output: 282


🏁 Script executed:

# Read the actual file to understand the context and mapping logic
cat -n app/composables/useDocsVersion.ts | sed -n '40,60p'

Repository: nuxt/nuxt.com

Length of output: 817


v5: '5x' and v4: '4x' dist-tag mappings do not exist on npm.

The npm registry for nuxt has no 5x or 4x dist-tags. The code at line 58 falls back to distTags.latest when these tags are missing, which currently resolves to version 4.3.1. This silently mislabels v5 documentation with a v4 version, creating an inconsistency between the intended version mapping and actual resolved versions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/composables/useDocsVersion.ts` around lines 47 - 50, The dist-tag map in
useDocsVersion.ts currently lists non-existent npm tags v5:'5x' and v4:'4x'
which causes the code that reads distTags (used around the fallback at line 58)
to silently resolve to distTags.latest; update the dist-tag mapping (the map
object in useDocsVersion) to use actual npm tags (e.g., map the v5 entry to
'next' and v4 to 'latest' or other real dist-tags your npm registry uses) and
change the resolution logic that looks up distTags['5x'] / distTags['4x'] to
explicitly check for existence and, if missing, choose the correct explicit
fallback (e.g., distTags.next for v5) and log or throw a clear warning instead
of silently using distTags.latest.

Comment on lines 5 to 10
return Promise.all([
queryCollectionNavigation(event, 'docsv3', ['titleTemplate']).then(data => data[0]?.children),
queryCollectionNavigation(event, 'docsv4', ['titleTemplate']).then(data => data[0]?.children),
queryCollectionNavigation(event, 'docsv5', ['titleTemplate']).then(data => data[0]?.children),
queryCollectionNavigation(event, 'blog')
]).then(data => data.flat())
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid null entries in the navigation payload when a collection has no root node.

The new docsv5 branch can return undefined via data[0]?.children, and flat() will keep that as a sparse/null entry in the API response.

Proposed fix
 export default defineEventHandler(async (event) => {
   return Promise.all([
-    queryCollectionNavigation(event, 'docsv3', ['titleTemplate']).then(data => data[0]?.children),
-    queryCollectionNavigation(event, 'docsv4', ['titleTemplate']).then(data => data[0]?.children),
-    queryCollectionNavigation(event, 'docsv5', ['titleTemplate']).then(data => data[0]?.children),
-    queryCollectionNavigation(event, 'blog')
+    queryCollectionNavigation(event, 'docsv3', ['titleTemplate']).then(data => data[0]?.children ?? []),
+    queryCollectionNavigation(event, 'docsv4', ['titleTemplate']).then(data => data[0]?.children ?? []),
+    queryCollectionNavigation(event, 'docsv5', ['titleTemplate']).then(data => data[0]?.children ?? []),
+    queryCollectionNavigation(event, 'blog').then(data => data ?? [])
   ]).then(data => data.flat())
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return Promise.all([
queryCollectionNavigation(event, 'docsv3', ['titleTemplate']).then(data => data[0]?.children),
queryCollectionNavigation(event, 'docsv4', ['titleTemplate']).then(data => data[0]?.children),
queryCollectionNavigation(event, 'docsv5', ['titleTemplate']).then(data => data[0]?.children),
queryCollectionNavigation(event, 'blog')
]).then(data => data.flat())
return Promise.all([
queryCollectionNavigation(event, 'docsv3', ['titleTemplate']).then(data => data[0]?.children ?? []),
queryCollectionNavigation(event, 'docsv4', ['titleTemplate']).then(data => data[0]?.children ?? []),
queryCollectionNavigation(event, 'docsv5', ['titleTemplate']).then(data => data[0]?.children ?? []),
queryCollectionNavigation(event, 'blog').then(data => data ?? [])
]).then(data => data.flat())
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/api/navigation.json.get.ts` around lines 5 - 10,
queryCollectionNavigation calls may yield undefined for branches like docsv5
because of data[0]?.children, causing sparse/null entries to remain after
.flat(); fix by normalizing each promise result to an array (e.g. replace
.then(data => data[0]?.children) with .then(data => data[0]?.children ?? []) or,
alternatively, after Promise.all use .then(results =>
results.flat().filter(Boolean)) so the exported navigation from this module has
no null/undefined entries; update the code referencing queryCollectionNavigation
and the final .then handler accordingly.

Copy link
Copy Markdown
Member

atinux commented Mar 2, 2026

omg it's happening

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
app/composables/useDocsVersion.ts (1)

47-60: ⚠️ Potential issue | 🟠 Major

Use real npm dist-tags; 5x/4x are not present and fallback hides bad mappings.

Line 47 and Line 48 map to dist-tags that currently don’t exist on https://registry.npmjs.org/nuxt, so Line 60 silently falls back to latest. That can mislabel docs versions (especially once latest moves).

Suggested fix
-const tagMap: Record<Version['shortTag'], string> = {
-  v5: '5x',
-  v4: '4x',
-  v3: '3x',
-  v2: '2x'
-}
+const tagMap: Record<Exclude<Version['shortTag'], 'v5'>, string> = {
+  v4: 'latest',
+  v3: '3x',
+  v2: '2x'
+}
...
-      Object.entries(tagMap).map(([shortTag]: [keyof typeof tagMap, string]) => {
-        // TODO: remove nightly fallback when Nuxt 5 is released
-        if (shortTag === 'v5') return [shortTag, distTags['5x'] ?? 'nightly']
-        return [shortTag, distTags[tagMap[shortTag]] ?? distTags.latest]
-      })
+      ([
+        ['v5', 'nightly'],
+        ...Object.entries(tagMap).map(([shortTag, tag]) => [shortTag, distTags[tag] ?? distTags.latest])
+      ])
#!/bin/bash
# Verify current nuxt dist-tag keys and whether 4x/5x exist.
curl -s https://registry.npmjs.org/nuxt \
  | jq -r '."dist-tags" | {keys: (keys|sort), has_4x: has("4x"), has_5x: has("5x"), latest: .latest}'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/composables/useDocsVersion.ts` around lines 47 - 60, The current
useDocsTags mapping in useDocsTags silently falls back to distTags.latest when
tagMap entries like '5x'/'4x' are missing, which can mislabel versions; update
the mapping in useDocsTags to check for the exact presence of
distTags[tagMap[shortTag]] (and for 'v5' keep the explicit nightly fallback if
desired) and avoid defaulting to distTags.latest for other tags—either return
undefined/omit the tag or log a warning when a mapped dist-tag is missing;
reference the tagMap constant and the useDocsTags function/distTags variable to
implement this check and adjust the return entries accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@app/composables/useDocsVersion.ts`:
- Around line 47-60: The current useDocsTags mapping in useDocsTags silently
falls back to distTags.latest when tagMap entries like '5x'/'4x' are missing,
which can mislabel versions; update the mapping in useDocsTags to check for the
exact presence of distTags[tagMap[shortTag]] (and for 'v5' keep the explicit
nightly fallback if desired) and avoid defaulting to distTags.latest for other
tags—either return undefined/omit the tag or log a warning when a mapped
dist-tag is missing; reference the tagMap constant and the useDocsTags
function/distTags variable to implement this check and adjust the return entries
accordingly.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a562f5 and b803d25.

📒 Files selected for processing (1)
  • app/composables/useDocsVersion.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/utils/content.ts (1)

30-43: Version-cleaning intent is ambiguous due to unused isV4.

At Line 40 and Line 42, isV4 is threaded through, but cleanNavigationPaths ignores it and cleanV4Path actually strips any \d.x. Consider renaming/removing the v4-specific contract so behavior is explicit.

♻️ Suggested cleanup
-function cleanV4Path(path: string): string {
+function cleanVersionPath(path: string): string {
   return path.replace(/\/\d\.x(?=\/|$)/, '')
 }

-function cleanNavigationPaths(navigation: ContentNavigationItem[], isV4: boolean): ContentNavigationItem[] {
+function cleanNavigationPaths(navigation: ContentNavigationItem[]): ContentNavigationItem[] {
   return navigation.map(item => ({
     ...item,
-    path: item.path ? cleanV4Path(item.path) : item.path,
-    children: item.children ? cleanNavigationPaths(item.children, isV4) : undefined
+    path: item.path ? cleanVersionPath(item.path) : item.path,
+    children: item.children ? cleanNavigationPaths(item.children) : undefined
   }))
 }

 export function findTitleTemplate(page: Ref<Docsv3CollectionItem | Docsv4CollectionItem | Docsv5CollectionItem>, navigation: Ref<ContentNavigationItem[]>): string {
@@
-  const isV4 = version.value.path === '/docs/4.x'
-  const searchPath = cleanV4Path(page.value.path)
-  const cleanNavigation = cleanNavigationPaths(navigation.value, isV4)
+  const searchPath = cleanVersionPath(page.value.path)
+  const cleanNavigation = cleanNavigationPaths(navigation.value)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/utils/content.ts` around lines 30 - 43, The code in findTitleTemplate
computes isV4 from useDocsVersion but never uses it because cleanNavigationPaths
ignores that flag and cleanV4Path already strips version segments; either remove
the v4-specific contract or make it explicit: either drop isV4 and call
cleanNavigationPaths(navigation.value) (and remove the unused parameter from
cleanNavigationPaths), or update cleanNavigationPaths to accept the isV4 boolean
and implement version-aware behavior; update findTitleTemplate accordingly and
ensure function signatures for cleanNavigationPaths (and any callers) and
cleanV4Path are consistent with the chosen approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/middleware/docs-version.global.ts`:
- Around line 2-3: The version-check condition in docs-version.global.ts is too
permissive; replace the plain startsWith checks with exact-segment matches (e.g.
use a RegExp like /^\/docs\/5\.x(\/|$)/ for each version) so paths such as
/docs/5.xfoo do not count as versioned; update the conditional that currently
checks to.path.startsWith('/docs/5.x') / '/docs/4.x' / '/docs/3.x' to use these
segment-aware regex tests (or check that the character after the segment is '/'
or end-of-string) and keep the redirect logic (to.fullPath.replace('/docs',
'/docs/4.x')) unchanged except triggered only when none of the segment-matches
succeed.

---

Nitpick comments:
In `@app/utils/content.ts`:
- Around line 30-43: The code in findTitleTemplate computes isV4 from
useDocsVersion but never uses it because cleanNavigationPaths ignores that flag
and cleanV4Path already strips version segments; either remove the v4-specific
contract or make it explicit: either drop isV4 and call
cleanNavigationPaths(navigation.value) (and remove the unused parameter from
cleanNavigationPaths), or update cleanNavigationPaths to accept the isV4 boolean
and implement version-aware behavior; update findTitleTemplate accordingly and
ensure function signatures for cleanNavigationPaths (and any callers) and
cleanV4Path are consistent with the chosen approach.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b803d25 and a3fde85.

📒 Files selected for processing (2)
  • app/middleware/docs-version.global.ts
  • app/utils/content.ts

Comment on lines +2 to 3
if (to.path.startsWith('/docs/') && !to.path.startsWith('/docs/5.x') && !to.path.startsWith('/docs/4.x') && !to.path.startsWith('/docs/3.x')) {
return to.fullPath.replace('/docs', '/docs/4.x')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Tighten version checks to segment boundaries.

Line 2 currently uses plain startsWith, so paths like /docs/5.xfoo are treated as versioned and skip the rewrite. Match exact version segments (/docs/5.x or /docs/5.x/...) to avoid accidental bypass.

Suggested hardening
 export default defineNuxtRouteMiddleware((to) => {
-  if (to.path.startsWith('/docs/') && !to.path.startsWith('/docs/5.x') && !to.path.startsWith('/docs/4.x') && !to.path.startsWith('/docs/3.x')) {
+  if (to.path.startsWith('/docs/') && !/^\/docs\/(?:5\.x|4\.x|3\.x)(?:\/|$)/.test(to.path)) {
     return to.fullPath.replace('/docs', '/docs/4.x')
   }
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (to.path.startsWith('/docs/') && !to.path.startsWith('/docs/5.x') && !to.path.startsWith('/docs/4.x') && !to.path.startsWith('/docs/3.x')) {
return to.fullPath.replace('/docs', '/docs/4.x')
export default defineNuxtRouteMiddleware((to) => {
if (to.path.startsWith('/docs/') && !/^\/docs\/(?:5\.x|4\.x|3\.x)(?:\/|$)/.test(to.path)) {
return to.fullPath.replace('/docs', '/docs/4.x')
}
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/middleware/docs-version.global.ts` around lines 2 - 3, The version-check
condition in docs-version.global.ts is too permissive; replace the plain
startsWith checks with exact-segment matches (e.g. use a RegExp like
/^\/docs\/5\.x(\/|$)/ for each version) so paths such as /docs/5.xfoo do not
count as versioned; update the conditional that currently checks
to.path.startsWith('/docs/5.x') / '/docs/4.x' / '/docs/3.x' to use these
segment-aware regex tests (or check that the character after the segment is '/'
or end-of-string) and keep the redirect logic (to.fullPath.replace('/docs',
'/docs/4.x')) unchanged except triggered only when none of the segment-matches
succeed.

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