add redirects into frontmatter & update deps#797
Conversation
✅ Deploy Preview for tanstack ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughRoute loaders and utilities now resolve frontmatter Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Route as Docs Route Loader
participant Resolver as resolveDocsRedirect
participant Manifest as fetchDocsRedirectManifest
participant Repo as Repo Files / Frontmatter
participant Docs as loadDocs
Client->>Route: GET /<lib>/<ver>/docs/old-page
Route->>Resolver: resolveDocsRedirect({repo,branch,docsRoot,docsPaths})
Resolver->>Manifest: fetchDocsRedirectManifest(repo,branch,docsRoot)
Manifest->>Repo: read docs tree & frontmatter
Repo-->>Manifest: return redirect entries
Manifest-->>Resolver: cached manifest
Resolver-->>Route: resolved target path or null
rect rgba(100,150,255,0.5)
Resolver-->>Route: returns /docs/new-page
Route->>Client: 308 Redirect to /<lib>/<ver>/docs/new-page
end
alt No redirect
Route->>Docs: loadDocs(branch, docsRoot, path)
Docs-->>Route: page content
Route-->>Client: 200 Rendered page
end
sequenceDiagram
actor Client
participant Route as Blog Route
participant Posts as Posts Collection
participant Mapper as Redirect Map
Client->>Route: GET /blog/old-slug
Route->>Posts: fetch allPosts (includes redirectFrom)
Posts->>Mapper: build/return redirect map (old → target slug)
Route->>Mapper: lookup normalized request path
rect rgba(100,150,255,0.5)
Mapper-->>Route: returns /blog/new-slug
Route->>Client: 308 Redirect to /blog/new-slug
end
alt No match
Route->>Client: continue to other handlers / 404
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/routes/blog.$.tsx (1)
26-54: Consider caching the redirect manifest.The redirect manifest is rebuilt on every request to
handleRedirects. SinceallPostsis a static import whose data doesn't change at runtime, the manifest could be computed once at module load time.♻️ Proposed optimization
+// Compute redirect manifest once at module load +const blogRedirectManifest = buildRedirectManifest( + allPosts.flatMap((post) => + (post.redirectFrom ?? []).map((redirectFrom) => ({ + from: normalizeBlogRedirectPath(redirectFrom), + to: post.slug, + source: post._meta.filePath, + })), + ), + { + label: 'blog posts', + formatTarget: (target) => `/blog/${target}`, + }, +) + function handleRedirects(docsPath: string) { - const redirectEntries = allPosts.flatMap((post) => - (post.redirectFrom ?? []).map((redirectFrom) => ({ - from: normalizeBlogRedirectPath(redirectFrom), - to: post.slug, - source: post._meta.filePath, - })), - ) - const redirectOwners = buildRedirectManifest(redirectEntries, { - label: 'blog posts', - formatTarget: (target) => `/blog/${target}`, - }) - const normalizedPaths = new Set([ normalizeBlogRedirectPath(docsPath), normalizeBlogRedirectPath(`/blog/${docsPath}`), ]) const redirectedPostSlug = Array.from(normalizedPaths).flatMap((path) => { - const redirectOwner = redirectOwners[path] + const redirectOwner = blogRedirectManifest[path] return redirectOwner ? [redirectOwner] : [] })[0]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/routes/blog`.$.tsx around lines 26 - 54, The redirect manifest is rebuilt on each call to handleRedirects; move the build out of the function so it runs once at module load: compute redirectEntries from allPosts and call buildRedirectManifest to produce a cached redirectOwners (or similar top-level constant) and have handleRedirects use that cached redirectOwners (keep normalizeBlogRedirectPath, normalizedPaths, and the final redirect throw logic intact so only the manifest construction is relocated).src/utils/docs.ts (1)
177-209: Promise.all fetches all markdown files in parallel without concurrency limits.When the redirect manifest cache is cold,
Promise.allon line 177 fetches all markdown files concurrently. WhilefetchRemoteuses raw.githubusercontent.com (which doesn't enforce rate limits like the GitHub API), this approach may cause unnecessary memory pressure with large doc sets. The 10-minute cache TTL should prevent this from being a frequent issue, but adding concurrency limits (e.g., with a library likep-limit) would provide cleaner resource management, especially during cold cache scenarios after server restarts.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/utils/docs.ts` around lines 177 - 209, The current Promise.all over markdownFiles (used to build entries) fetches every file in parallel via fetchRepoFile which can spike memory/IO; introduce a concurrency limiter (e.g., p-limit) around the markdownFiles.map work so only N fetchRepoFile calls run at once, wrap the async mapping logic (the canonicalPath check, fetchRepoFile, extractFrontMatter and subsequent redirect mapping) in the limiter and await Promise.all on the limited tasks instead of raw Promise.all; reference the Promise.all usage, fetchRepoFile, getCanonicalDocsPath, extractFrontMatter and normalizeDocsRedirectPath when updating the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs-info.md`:
- Around line 49-56: The example code block in docs-info.md is malformed: the
inner TypeScript JSX snippet (export function App()) ends with `;``` instead of
the proper closing triple backticks; update the closing fence for the inner
```tsx title="app.tsx" block so the example ends with ``` (three backticks)
followed by the outer markdown fences, ensuring the `export function App()`
snippet is properly closed.
---
Nitpick comments:
In `@src/routes/blog`.$.tsx:
- Around line 26-54: The redirect manifest is rebuilt on each call to
handleRedirects; move the build out of the function so it runs once at module
load: compute redirectEntries from allPosts and call buildRedirectManifest to
produce a cached redirectOwners (or similar top-level constant) and have
handleRedirects use that cached redirectOwners (keep normalizeBlogRedirectPath,
normalizedPaths, and the final redirect throw logic intact so only the manifest
construction is relocated).
In `@src/utils/docs.ts`:
- Around line 177-209: The current Promise.all over markdownFiles (used to build
entries) fetches every file in parallel via fetchRepoFile which can spike
memory/IO; introduce a concurrency limiter (e.g., p-limit) around the
markdownFiles.map work so only N fetchRepoFile calls run at once, wrap the async
mapping logic (the canonicalPath check, fetchRepoFile, extractFrontMatter and
subsequent redirect mapping) in the limiter and await Promise.all on the limited
tasks instead of raw Promise.all; reference the Promise.all usage,
fetchRepoFile, getCanonicalDocsPath, extractFrontMatter and
normalizeDocsRedirectPath when updating the code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 9fa0a660-5190-4142-b3db-acb1d7c90ed0
📒 Files selected for processing (8)
content-collections.tsdocs-info.mdsrc/routes/$libraryId/$version.docs.$.tsxsrc/routes/$libraryId/$version.docs.framework.$framework.$.tsxsrc/routes/blog.$.tsxsrc/utils/docs.tssrc/utils/documents.server.tssrc/utils/redirects.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
package.json (1)
155-157: Node 20+ requirement is a breaking change for contributors and deployments.Bumping the minimum Node version from 18 to 20 is reasonable since Node 20 is the current LTS. Ensure CI/CD pipelines, deployment environments (Netlify), and contributor documentation are updated to reflect this requirement.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@package.json` around lines 155 - 157, The package.json engines field now requires Node ">=20.0.0", which is a breaking change for contributors and deployments; update all relevant configurations and docs to match this new minimum by: changing CI workflows (GitHub Actions, etc.) and any Dockerfiles to use Node 20 images, updating deployment platform settings (e.g., Netlify runtime/node version) to Node 20, and revising contributor/setup docs and README to state the Node >=20 requirement; reference the package.json "engines" entry when making these edits so everything stays consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@package.json`:
- Around line 155-157: The package.json engines field now requires Node
">=20.0.0", which is a breaking change for contributors and deployments; update
all relevant configurations and docs to match this new minimum by: changing CI
workflows (GitHub Actions, etc.) and any Dockerfiles to use Node 20 images,
updating deployment platform settings (e.g., Netlify runtime/node version) to
Node 20, and revising contributor/setup docs and README to state the Node >=20
requirement; reference the package.json "engines" entry when making these edits
so everything stays consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5b5d04ba-0e86-4031-a288-beef859f6155
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (1)
package.json
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@package.json`:
- Line 138: Update the Node engine constraint in package.json: replace the
current "node": ">=20.0.0" entry with "node": "^20.19.0 || >=22.12.0" so the
engines field matches the requirements of vite@8, `@vitejs/plugin-react`@6 and
oxlint@1.57.0; edit the "engines" -> "node" property accordingly and ensure
package.json remains valid JSON after the change.
In `@src/components/Doc.tsx`:
- Around line 124-127: In the Doc component, the anchor uses pagePath (from
DocProps) without checking for undefined, which can produce href="undefined.md";
guard this by only rendering the <a> (or computing its href) when pagePath is
truthy: update the Doc component's render logic around the anchor that
references {pagePath}.md to conditionally render the anchor (or set a safe
fallback) so the href is never built from an undefined pagePath.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6df725f0-a743-461d-bb43-0ad8a4c3d3b6
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
.oxlintrc.jsoneslint.config.mjspackage.jsonsrc/components/Doc.tsxsrc/components/DocsLayout.tsxsrc/components/StackBlitzEmbed.tsx
💤 Files with no reviewable changes (1)
- eslint.config.mjs
✅ Files skipped from review due to trivial changes (1)
- src/components/StackBlitzEmbed.tsx
package.json
Outdated
| }, | ||
| "engines": { | ||
| "node": ">=18.0.0" | ||
| "node": ">=20.0.0" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Verify published engine constraints for upgraded tooling.
npm view vite@8 engines --json
npm view `@vitejs/plugin-react`@6 engines --json
npm view oxlint@1.57.0 engines --jsonRepository: TanStack/tanstack.com
Length of output: 378
Update Node engine constraint to match toolchain requirements.
The current "node": ">=20.0.0" is incompatible with the upgraded toolchain. vite@8, @vitejs/plugin-react@6, and oxlint@1.57.0 all require "node": "^20.19.0 || >=22.12.0". Change the constraint to "node": "^20.19.0 || >=22.12.0" to prevent install/build failures on Node versions 20.0.0 through 20.18.x.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` at line 138, Update the Node engine constraint in package.json:
replace the current "node": ">=20.0.0" entry with "node": "^20.19.0 ||
>=22.12.0" so the engines field matches the requirements of vite@8,
`@vitejs/plugin-react`@6 and oxlint@1.57.0; edit the "engines" -> "node" property
accordingly and ensure package.json remains valid JSON after the change.
| <a href={`${pagePath}.md`} className="sr-only"> | ||
| AI/LLM: This documentation page is available in plain markdown format at | ||
| {pagePath}.md | ||
| </a> |
There was a problem hiding this comment.
Guard the markdown link when pagePath is absent.
pagePath is optional in DocProps, so this can produce href="undefined.md".
🐛 Proposed fix
- <a href={`${pagePath}.md`} className="sr-only">
- AI/LLM: This documentation page is available in plain markdown format at
- {pagePath}.md
- </a>
+ {pagePath ? (
+ <a href={`${pagePath}.md`} className="sr-only">
+ AI/LLM: This documentation page is available in plain markdown format at
+ {pagePath}.md
+ </a>
+ ) : null}📝 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.
| <a href={`${pagePath}.md`} className="sr-only"> | |
| AI/LLM: This documentation page is available in plain markdown format at | |
| {pagePath}.md | |
| </a> | |
| {pagePath ? ( | |
| <a href={`${pagePath}.md`} className="sr-only"> | |
| AI/LLM: This documentation page is available in plain markdown format at | |
| {pagePath}.md | |
| </a> | |
| ) : null} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/components/Doc.tsx` around lines 124 - 127, In the Doc component, the
anchor uses pagePath (from DocProps) without checking for undefined, which can
produce href="undefined.md"; guard this by only rendering the <a> (or computing
its href) when pagePath is truthy: update the Doc component's render logic
around the anchor that references {pagePath}.md to conditionally render the
anchor (or set a safe fallback) so the href is never built from an undefined
pagePath.

Summary by CodeRabbit
New Features
Documentation
Bug Fixes / Accessibility
Chores