Conversation
### Summary of Changes - Added `rimraf` as a devDependency. - Updated `zod` version from 4.1.12 to 4.3.6 in multiple dependencies. - Introduced redirects in middleware for `/SKILL.md` and `/SKILLS.md` to `/llms.txt`. - Created new routes for handling LLM text retrieval and redirection. - Updated `llms.txt` to include sorted URLs for documentation and API pages. ### Context These changes enhance the documentation routing and ensure compatibility with the latest package versions.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
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:
📝 WalkthroughWalkthroughAdds plain-text LLM endpoints and redirects: new routes for Changes
Sequence Diagram(s)sequenceDiagram
actor Client
participant Router as "Next.js Router"
participant Middleware as "Middleware"
participant LLMS_Index as "/llms.txt"
participant Sources as "source / apiSource"
Client->>Router: GET /llms.txt
Router->>Middleware: run matchers
Middleware-->>Router: pass through or 307 redirect
Router->>LLMS_Index: GET(request)
LLMS_Index->>Sources: source.getPages(), apiSource.getPages()
Sources-->>LLMS_Index: lists of pages
LLMS_Index->>LLMS_Index: strip prefixes, dedupe, sort (stringCompare)
LLMS_Index-->>Client: 200 text/plain (header + base URLs + newline list)
sequenceDiagram
actor Client
participant Router as "Next.js Router"
participant Middleware as "Middleware"
participant LLMS_Dyn as "/llms/[[...slug]]"
participant Sources as "source / apiSource"
participant LLMText as "getLLMText"
Client->>Router: GET /llms/docs/some-page
Router->>Middleware: run matchers
Middleware-->>Router: pass through
Router->>LLMS_Dyn: GET(request, { params: ['docs','some-page'] })
LLMS_Dyn->>Sources: source.getPage('some-page')
Sources-->>LLMS_Dyn: page or null
alt page found
LLMS_Dyn->>LLMText: getLLMText(page)
LLMText-->>LLMS_Dyn: plain text
LLMS_Dyn-->>Client: 200 text/plain
else not found
LLMS_Dyn-->>Client: 404 or 307 redirect to /llms.txt
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 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.
Pull request overview
This PR updates the docs app’s LLM-oriented endpoints and redirects, while also refreshing lockfile dependencies (including a zod bump) to keep tooling up to date.
Changes:
- Add middleware redirects for
/SKILL.mdand/SKILLS.mdto/llms.txt. - Introduce
/llms/*route handling to fetch per-page LLM text and add/llm.txt→/llms.txtredirect. - Revise
/llms.txtoutput to a deduplicated, sorted list of LLM route URLs.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Updates dependency graph and adds a new workspace importer entry. |
| docs/src/middleware.ts | Adds redirects for SKILL(S).md and updates middleware matcher. |
| docs/src/app/llms/[[...slug]]/route.ts | Adds dynamic route to return LLM text for docs/api pages and redirect empty slug to /llms.txt. |
| docs/src/app/llms.txt/route.ts | Changes llms.txt to output a sorted, deduped list of LLM routes (instead of concatenated page contents). |
| docs/src/app/llm.txt/route.ts | Adds /llm.txt redirect to /llms.txt. |
| claude/CLAUDE-KNOWLEDGE.md | Documents the intended llms.txt format and related redirects. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Greptile SummaryThis PR adds LLM-friendly documentation routing to the Stack Auth docs site: a new
Confidence Score: 4/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Incoming Request] --> MW{Middleware}
MW -->|/SKILL.md /SKILLS.md /skill.md /skills.md| RD1[307 → /llms.txt]
MW -->|/docs or /api\nAccept: text/plain| RW[Rewrite → /llms.mdx/...]
MW -->|otherwise| NEXT[NextResponse.next]
NEXT -->|GET /llm.txt| LLM1[llm.txt route\n307 → /llms.txt]
NEXT -->|GET /llms.txt| LLM2[llms.txt route\nSorted URL list]
NEXT -->|GET /llms/docs/...| LLM3[llms slug route\nResolvePage docs]
NEXT -->|GET /llms/api/...| LLM4[llms slug route\nResolvePage api]
NEXT -->|GET /llms empty slug| RD2[307 → /llms.txt]
LLM3 -->|page found| TXT1[getLLMText → 200 text/plain]
LLM3 -->|not found| E404[404 NextResponse]
LLM4 -->|page found| TXT2[getLLMText → 200 text/plain]
LLM4 -->|not found| E404
RW -->|GET /llms.mdx/...| MDXR[llms.mdx route\ngetLLMText]
MDXR -->|page found| TXT3[200 text/plain]
MDXR -->|not found| RD3[307 → /llms.txt]
Reviews (4): Last reviewed commit: "Update LLM route handling and improve UR..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@claude/CLAUDE-KNOWLEDGE.md`:
- Around line 106-107: The docs claim `/skill.md` and `/skills.md` redirect to
`/llms.txt` but the middleware only handles `/SKILL.md` and `/SKILLS.md`; update
the redirect logic in middleware.ts so the aliases align by either adding
lowercase entries for `/skill.md` and `/skills.md` to the
redirectRules/getRedirects array or normalize incoming request paths (e.g.,
toLowerCase()) in the handleRedirects/middleware function before matching;
ensure the same redirect target `/llms.txt` is used so the documentation and
implementation match.
In `@docs/src/app/llms.txt/route.ts`:
- Around line 19-27: Replace the hard-coded production base URLs in the body
array with dynamic base URLs derived from the incoming request origin rather
than "https://docs.stack-auth.com"; compute the origin using the request (e.g.,
new URL(request.url).origin or request.headers.get('host') + protocol) and then
build the two base strings (e.g., `${origin}/llms/docs/` and
`${origin}/llms/api/`) when composing body alongside docsUrls and apiUrls;
update the code that constructs body (the block referencing body, docsUrls,
apiUrls, stringCompare) to use those dynamic base variables so /llms.txt points
to the same host/environment as the request.
In `@docs/src/app/llms/`[[...slug]]/route.ts:
- Around line 38-40: The route currently redirects missing LLM pages to "/",
which returns the HTML homepage; replace that behavior to return a 404 instead
by calling Next's notFound() helper (import { notFound } from "next/navigation")
in the same block that checks page (the if (!page) branch), ensuring the route
returns a proper 404 response for unknown /llms/... resources instead of
redirecting.
- Around line 42-50: Remove the broad try/catch that swallows errors around
getLLMText and the NextResponse creation: delete the catch block (and
surrounding try) so exceptions from getLLMText or param parsing are allowed to
propagate (or rethrow with context) instead of returning a generic 500 or empty
response; update any similar catch-all around the second response block (the
code covering lines 54-67) the same way so failures fail loud rather than being
masked.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d4644b2f-dd98-4521-9de5-11bebf61e861
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
claude/CLAUDE-KNOWLEDGE.mddocs/src/app/llm.txt/route.tsdocs/src/app/llms.txt/route.tsdocs/src/app/llms/[[...slug]]/route.tsdocs/src/middleware.ts
### Summary of Changes - Updated middleware to include additional redirects for `/skill.md` and `/skills.md` to `/llms.txt`. - Refactored redirect logic in LLM routes to use `NextResponse.redirect` for improved clarity and consistency. - Adjusted URL handling in `llms.txt` to ensure proper relative URL extraction for documentation and API pages. These changes improve the routing logic and ensure better handling of various URL formats.
### Summary of Changes - Replaced `NextResponse.redirect` with `notFound()` for better error handling when a page is not found in the LLM route. - Simplified the `GET` function in `llms.txt` to dynamically generate base URLs for documentation and API pages based on the request URL. - Removed unnecessary try-catch blocks in both routes to streamline the code. These updates enhance the clarity and efficiency of the LLM routing logic.
|
@greptile-ai review |
### Summary of Changes - Replaced `notFound()` with a `NextResponse` for 404 status in the LLM route to improve error handling. - Added a try-catch block to handle potential errors when generating LLM text, returning a 500 status on failure. - Updated URL generation in `llms.txt` to dynamically construct base URLs using the request's origin. These modifications enhance the robustness and clarity of the LLM routing logic.
|
@greptile-ai review |
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 `@docs/src/app/llms.mdx/`[[...slug]]/route.ts:
- Around line 21-23: When page is missing (the if (!page) branch) do not
redirect to '/'—update the NextResponse.redirect call so it points to
'/llms.txt' instead of '/' (keep the 307 status) so consumers receive the LLM
text index; locate the conditional around NextResponse.redirect in this route.ts
and replace the target URL accordingly (still use NextResponse.redirect and the
same request.url context).
In `@docs/src/app/llms.txt/route.ts`:
- Around line 13-25: The current code blindly strips "/docs" and "/api" prefixes
using replace, which also alters URLs like "/docs-old" or "/apiary"; update the
loops over source.getPages() and apiSource.getPages() to first validate the
namespace with a strict prefix check (e.g., url === "/docs" or
url.startsWith("/docs/") and similarly for "/api"), and only then compute
relativeUrl by slicing off the exact prefix before adding to docsUrls/apiUrls;
if a page.url does not match the expected namespace, throw or assert with a
clear error containing the offending page.url and the source (fail-fast) rather
than silently producing a broken relative path.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 638bb8ca-dc39-4a87-a637-59f09f131d31
📒 Files selected for processing (4)
docs/src/app/llms.mdx/[[...slug]]/route.tsdocs/src/app/llms.txt/route.tsdocs/src/app/llms/[[...slug]]/route.tsdocs/src/middleware.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- docs/src/middleware.ts
- docs/src/app/llms/[[...slug]]/route.ts
### Summary of Changes - Set `revalidate` to false for statically generated page content paths in `route.ts`. - Updated the redirect URL in the LLM route to point to `/llms.txt` instead of the root. - Enhanced URL validation in `llms.txt` to ensure proper prefixes for documentation and API pages, throwing errors for unexpected URLs. These changes improve the routing logic and ensure better handling of page URLs.
|
@greptile-ai review |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
docs/src/app/llms/[[...slug]]/route.ts (1)
43-52:⚠️ Potential issue | 🟠 MajorRemove the catch-all around
getLLMTextand let failures surface.This block swallows all runtime errors, logs, then returns a generic 500, which hides actionable failure context and conflicts with the repo rule for TS files.
♻️ Proposed fix
- try { - return new NextResponse(await getLLMText(page), { - headers: { - 'Content-Type': 'text/plain; charset=utf-8', - }, - }); - } catch (error) { - console.error('Error generating LLM text:', error); - return new NextResponse('Error generating content', { status: 500 }); - } + return new NextResponse(await getLLMText(page), { + headers: { + 'Content-Type': 'text/plain; charset=utf-8', + }, + });As per coding guidelines
**/*.{ts,tsx}: NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error) or similar. UserunAsynchronouslyorrunAsynchronouslyWithAlertinstead for error handling.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/app/llms/`[[...slug]]/route.ts around lines 43 - 52, Remove the catch-all around getLLMText so runtime errors bubble instead of being swallowed: delete the try/catch and return the NextResponse created from await getLLMText(page) directly (i.e., call new NextResponse(await getLLMText(page), { headers: {...} }) without wrapping in try/catch). Alternatively, if you need controlled async error reporting use runAsynchronously or runAsynchronouslyWithAlert to invoke getLLMText(page) and pass the result into NextResponse so you comply with the repo rule (referencing getLLMText, runAsynchronously/runAsynchronouslyWithAlert, and NextResponse).
🧹 Nitpick comments (2)
docs/src/app/llms/[[...slug]]/route.ts (1)
39-39: Use an explicit nullish check forpage.Prefer
if (page == null)overif (!page)to avoid broad truthy/falsy checks and keep the guard semantically precise.♻️ Proposed fix
- if (!page) { + if (page == null) { return new NextResponse(null, { status: 404 }); }As per coding guidelines Unless very clearly equivalent from types, prefer explicit null/undefinedness checks over boolean checks, e.g.,
foo == nullinstead of!foo.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/app/llms/`[[...slug]]/route.ts at line 39, Replace the broad falsy check "if (!page)" with an explicit nullish check so only null/undefined are guarded; update the conditional that references the local variable page (the if-block starting with "if (!page)") to use "page == null" (or "page === null || page === undefined") to avoid rejecting valid falsy values like empty string or 0 while keeping the same guard semantics.docs/src/app/llms.mdx/[[...slug]]/route.ts (1)
27-29: Consider using structured error handling instead ofconsole.error.The coding guidelines state to never use
.catch(console.error)or similar patterns. While this is a route handler that does return a proper 500 response, theconsole.errorcall could be replaced with a more structured logging approach or the project's preferred error handling utility.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/app/llms.mdx/`[[...slug]]/route.ts around lines 27 - 29, Replace the direct console.error call in the catch block that logs "Error generating LLM text" with the project's structured logging/error-reporting utility (e.g., use processLogger.error or Sentry/monitoring capture function) and include the error object and context; keep returning new NextResponse('Error generating content', { status: 500 }) but ensure you import and call the project's logger/reporting function (from the same module where other handlers use it) so errors are recorded in structured logs/monitoring rather than via console.error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@docs/src/app/llms/`[[...slug]]/route.ts:
- Around line 43-52: Remove the catch-all around getLLMText so runtime errors
bubble instead of being swallowed: delete the try/catch and return the
NextResponse created from await getLLMText(page) directly (i.e., call new
NextResponse(await getLLMText(page), { headers: {...} }) without wrapping in
try/catch). Alternatively, if you need controlled async error reporting use
runAsynchronously or runAsynchronouslyWithAlert to invoke getLLMText(page) and
pass the result into NextResponse so you comply with the repo rule (referencing
getLLMText, runAsynchronously/runAsynchronouslyWithAlert, and NextResponse).
---
Nitpick comments:
In `@docs/src/app/llms.mdx/`[[...slug]]/route.ts:
- Around line 27-29: Replace the direct console.error call in the catch block
that logs "Error generating LLM text" with the project's structured
logging/error-reporting utility (e.g., use processLogger.error or
Sentry/monitoring capture function) and include the error object and context;
keep returning new NextResponse('Error generating content', { status: 500 }) but
ensure you import and call the project's logger/reporting function (from the
same module where other handlers use it) so errors are recorded in structured
logs/monitoring rather than via console.error.
In `@docs/src/app/llms/`[[...slug]]/route.ts:
- Line 39: Replace the broad falsy check "if (!page)" with an explicit nullish
check so only null/undefined are guarded; update the conditional that references
the local variable page (the if-block starting with "if (!page)") to use "page
== null" (or "page === null || page === undefined") to avoid rejecting valid
falsy values like empty string or 0 while keeping the same guard semantics.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 4ccfbe22-6bc0-418f-bd34-06297d6381b2
📒 Files selected for processing (3)
docs/src/app/llms.mdx/[[...slug]]/route.tsdocs/src/app/llms.txt/route.tsdocs/src/app/llms/[[...slug]]/route.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/src/app/llms.txt/route.ts
### Summary of Changes - Added 'rolldown' as a new optional dependency in `pnpm-lock.yaml`. - Simplified middleware logic to handle redirects for `/skill.md` and `/skills.md` in a case-insensitive manner. - Refactored the `resolvePage` function in `route.ts` to accept only defined slugs, improving clarity. - Enhanced URL collection logic in `llms.txt` to streamline the extraction of relative URLs for documentation and API pages. These updates improve dependency management and enhance the routing logic for better URL handling.
### Summary of Changes - Introduced a new `GET` function in `route.ts` to aggregate and return LLM texts from both local and API sources. - Set `revalidate` to false to optimize static content delivery. - Implemented response formatting to return plain text with appropriate headers. This addition enhances the LLM functionality by consolidating text retrieval into a single endpoint, improving efficiency and usability.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
docs/src/app/llms/[[...slug]]/route.ts (1)
35-37: Prefer explicit null check over boolean check.Per coding guidelines, prefer explicit null/undefinedness checks over boolean checks. Use
page == nullinstead of!page.- if (!page) { + if (page == null) { return new NextResponse(null, { status: 404 }); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/app/llms/`[[...slug]]/route.ts around lines 35 - 37, Replace the boolean negation check on the page variable with an explicit null/undefined check: locate the conditional that currently reads if (!page) and change it to use page == null so it only treats null/undefined as missing; keep the existing return new NextResponse(null, { status: 404 }) behavior intact (the change should be made around the same conditional that references page in route.ts).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/src/app/llms/`[[...slug]]/route.ts:
- Around line 35-37: Replace the boolean negation check on the page variable
with an explicit null/undefined check: locate the conditional that currently
reads if (!page) and change it to use page == null so it only treats
null/undefined as missing; keep the existing return new NextResponse(null, {
status: 404 }) behavior intact (the change should be made around the same
conditional that references page in route.ts).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d636e1ee-3a06-4cac-adb8-54d87b9ddd51
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (5)
docs/src/app/llms-full.txt/route.tsdocs/src/app/llms.mdx/[[...slug]]/route.tsdocs/src/app/llms.txt/route.tsdocs/src/app/llms/[[...slug]]/route.tsdocs/src/middleware.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/src/app/llms.mdx/[[...slug]]/route.ts
- docs/src/middleware.ts
- docs/src/app/llms.txt/route.ts
Summary of Changes
rimrafas a devDependency.zodversion from 4.1.12 to 4.3.6 in multiple dependencies./SKILL.mdand/SKILLS.mdto/llms.txt.llms.txtto include sorted URLs for documentation and API pages.Context
These changes enhance the documentation routing and ensure compatibility with the latest package versions.
Summary by CodeRabbit
New Features
Bug Fixes / Redirects
Documentation