-
Notifications
You must be signed in to change notification settings - Fork 25
Create custom documentation framework #2919
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
||
| return ( | ||
| <div className="flex items-center gap-1 rounded-md border p-1"> | ||
| <Link href={getOtherLanguageUrl().replace("/typescript", "/typescript")}> |
Check warning
Code scanning / CodeQL
Replacement of a substring with itself Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
The best way to fix this problem is to remove the meaningless call to .replace("/typescript", "/typescript") (and similarly, .replace("/python", "/python") on line 122). These calls do not alter the string, and their presence reduces code clarity. Instead, getOtherLanguageUrl() is properly responsible for returning the URL for the other language, and we should use it directly as the href for each <Link>. Thus, in this file, lines where unnecessary self-replacement occurs (lines 113 and 122) should be replaced with direct usage of getOtherLanguageUrl(). No new imports or methods are needed.
-
Copy modified line R113 -
Copy modified line R122
| @@ -110,7 +110,7 @@ | ||
|
|
||
| return ( | ||
| <div className="flex items-center gap-1 rounded-md border p-1"> | ||
| <Link href={getOtherLanguageUrl().replace("/typescript", "/typescript")}> | ||
| <Link href={getOtherLanguageUrl()}> | ||
| <Button | ||
| variant={currentLanguage === "typescript" ? "secondary" : "ghost"} | ||
| size="sm" | ||
| @@ -119,7 +119,7 @@ | ||
| TypeScript | ||
| </Button> | ||
| </Link> | ||
| <Link href={getOtherLanguageUrl().replace("/python", "/python")}> | ||
| <Link href={getOtherLanguageUrl()}> | ||
| <Button | ||
| variant={currentLanguage === "python" ? "secondary" : "ghost"} | ||
| size="sm" |
| TypeScript | ||
| </Button> | ||
| </Link> | ||
| <Link href={getOtherLanguageUrl().replace("/python", "/python")}> |
Check warning
Code scanning / CodeQL
Replacement of a substring with itself Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
To fix the problem, we should ensure that each language switcher button links to the correct language. The logic already computes getOtherLanguageUrl(), which switches the slug based on the current language. The subsequent calls to .replace("/typescript", "/typescript") and .replace("/python", "/python") are ineffective and unnecessary, possibly left over from a previous implementation. The correct approach is to link directly to the output of getOtherLanguageUrl(), since it returns the right URL for switching between TypeScript and Python.
Therefore, in both link components (lines 113 and 122), simply remove the redundant .replace(...) calls and use getOtherLanguageUrl() directly. No additional method definitions or imports are necessary, and no change to surrounding logic is needed.
-
Copy modified line R113 -
Copy modified line R122
| @@ -110,7 +110,7 @@ | ||
|
|
||
| return ( | ||
| <div className="flex items-center gap-1 rounded-md border p-1"> | ||
| <Link href={getOtherLanguageUrl().replace("/typescript", "/typescript")}> | ||
| <Link href={getOtherLanguageUrl()}> | ||
| <Button | ||
| variant={currentLanguage === "typescript" ? "secondary" : "ghost"} | ||
| size="sm" | ||
| @@ -119,7 +119,7 @@ | ||
| TypeScript | ||
| </Button> | ||
| </Link> | ||
| <Link href={getOtherLanguageUrl().replace("/python", "/python")}> | ||
| <Link href={getOtherLanguageUrl()}> | ||
| <Button | ||
| variant={currentLanguage === "python" ? "secondary" : "ghost"} | ||
| size="sm" |
|
|
||
| return ( | ||
| <Link | ||
| href={href} |
Check failure
Code scanning / CodeQL
Stored cross-site scripting High
stored value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
To address the vulnerability, all data used in a URL path (slug) must be sanitized before use. The best way is to encode or sanitize item.slug so that only valid, safe path and URL characters are present. This can be achieved by encoding the slug with encodeURIComponent before using it as a path segment in the href.
Specifically, in apps/framework-docs-v2/src/components/navigation/side-nav.tsx in the NavItemComponent, update the line where href is constructed to encode item.slug using encodeURIComponent. All usages of slugs in URLs should undergo the same process. Imports are not needed for encodeURIComponent.
-
Copy modified line R40
| @@ -37,7 +37,7 @@ | ||
| level?: number; | ||
| }) { | ||
| const pathname = usePathname(); | ||
| const href = `/${language}/${item.slug}`; | ||
| const href = `/${language}/${encodeURIComponent(item.slug)}`; | ||
| const isActive = pathname === href; | ||
| const hasChildren = item.children && item.children.length > 0; | ||
| const [isOpen, setIsOpen] = useState( |
| cleaned = cleaned.replace(/<\/[A-Z][A-Za-z0-9]*>/g, ""); | ||
|
|
||
| // Remove HTML comments | ||
| cleaned = cleaned.replace(/<!--[\s\S]*?-->/g, ""); |
Check failure
Code scanning / CodeQL
Incomplete multi-character sanitization High
<!--
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 1 month ago
To robustly remove HTML comments in a way that prevents incomplete multi-character replacement, we should apply the regular expression replacement repeatedly until no further replacements can occur. This catches cases where removing one comment exposes another, or when constructs can be manipulated by attackers to evade a single-pass replacement. Edit the cleanContent function in apps/framework-docs-v2/src/lib/llms-generator.ts, replacing line 107 (the HTML comment removal) with a loop that continues replacing until the string stabilizes. No additional dependencies are required; vanilla JS suffices for this fix.
-
Copy modified lines R107-R112
| @@ -104,7 +104,12 @@ | ||
| cleaned = cleaned.replace(/<\/[A-Z][A-Za-z0-9]*>/g, ""); | ||
|
|
||
| // Remove HTML comments | ||
| cleaned = cleaned.replace(/<!--[\s\S]*?-->/g, ""); | ||
| // Repeatedly remove HTML comments until none are left (prevents incomplete sanitization) | ||
| let prev; | ||
| do { | ||
| prev = cleaned; | ||
| cleaned = cleaned.replace(/<!--[\s\S]*?-->/g, ""); | ||
| } while (cleaned !== prev); | ||
|
|
||
| // Clean up excessive whitespace | ||
| cleaned = cleaned.replace(/\n{3,}/g, "\n\n"); |
| TypeScript | ||
| </Button> | ||
| </Link> | ||
| <Link href={getOtherLanguageUrl().replace("/python", "/python")}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Redundant URL Replacement Causes Language Switch Error
The LanguageSwitcher component's links use getOtherLanguageUrl() followed by redundant no-op .replace() calls. Since getOtherLanguageUrl() already returns the URL for the opposite language, this causes one of the language buttons to navigate to the wrong language.
| const isActive = pathname === href; | ||
| const hasChildren = item.children && item.children.length > 0; | ||
| const [isOpen, setIsOpen] = useState( | ||
| isActive || (hasChildren && item.children?.some((child) => pathname.includes(child.slug))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: String Property Used as Array
The NavItem.slug property is defined as a string, but the code attempts to call .join("/") on it when generating component keys and navigation hrefs. This will cause a runtime error.
Additional Locations (1)
| import { redirect } from "next/navigation"; | ||
|
|
||
| export async function GET() { | ||
| redirect("/api/llms.txt?language=typescript"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Query Parameter Mismatch in API Redirects
The redirects for llms.txt in both TypeScript and Python use language as a query parameter. The /api/llms.txt endpoint, however, expects the lang parameter. This mismatch means the API does not correctly receive the intended language.
Note
Introduce a new Next.js docs app with TS/Python content, Pagefind search, PostHog analytics, llms.txt generation, and code-snippet testing.
apps/framework-docs-v2with TypeScript setup, Tailwind, shadcn/ui, and file-based markdown content incontent/{typescript,python}./typescript/*,/python/*with layouts, dynamic pages, breadcrumbs, TOC, and side nav.public/pagefind).next.config.{js,ts}.GET /api/llms.txt?lang=typescript|pythonto generate language-specific llms.txt from markdown.src/lib/snippet-tester.ts) and scriptscripts/test-snippets.tswith Turbo tasktest:snippets.scripts/migrate-content.tsto split MDX into TS/PY markdown.turbo.jsonenv additions;package.jsonscripts for build/indexing.index.mdx,quickstart.md) for both languages.Written by Cursor Bugbot for commit 3913799. This will update automatically on new commits. Configure here.