From 00a14ed37f367295573c31220ed7fec16a679cb5 Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:13:18 -0400 Subject: [PATCH 1/9] chore: prepare infrastructure for README image rendering - Add default_branch field to GitHubRepository interface - Register raw.githubusercontent.com in images.remotePatterns --- next.config.ts | 4 ++++ src/lib/github.ts | 1 + 2 files changed, 5 insertions(+) diff --git a/next.config.ts b/next.config.ts index ec537f2..7954bdc 100644 --- a/next.config.ts +++ b/next.config.ts @@ -8,6 +8,10 @@ const nextConfig = { protocol: 'https', hostname: 'avatars.githubusercontent.com', }, + { + protocol: 'https', + hostname: 'raw.githubusercontent.com', + }, ], }, }; diff --git a/src/lib/github.ts b/src/lib/github.ts index 34719ca..4ec9f44 100644 --- a/src/lib/github.ts +++ b/src/lib/github.ts @@ -47,6 +47,7 @@ export interface GitHubRepository { url: string | null; } | null; topics: string[]; + default_branch: string; } export interface GitHubCommit { From 83fc104a8743a526c6b92f2abcb4d686f9ae1a2f Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:13:22 -0400 Subject: [PATCH 2/9] chore: add rehype-raw for HTML rendering in markdown rehype-raw allows react-markdown to parse and render raw HTML tags found in GitHub READMEs (e.g. ,

). --- package-lock.json | 174 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 2 files changed, 173 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 37ca172..db37a3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "github-explorer-dashboard", - "version": "0.3.0", + "version": "0.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "github-explorer-dashboard", - "version": "0.3.0", + "version": "0.3.2", "dependencies": { "@base-ui/react": "^1.5.0", "class-variance-authority": "^0.7.1", @@ -18,6 +18,7 @@ "react-dom": "19.2.4", "react-markdown": "^10.1.0", "recharts": "^3.8.0", + "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "shadcn": "^4.7.0", "tailwind-merge": "^3.6.0", @@ -4620,6 +4621,18 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", @@ -6094,6 +6107,64 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", @@ -6121,6 +6192,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -6134,6 +6224,23 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/headers-polyfill": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-5.0.1.tgz", @@ -6180,6 +6287,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -9163,6 +9280,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -9643,6 +9772,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", @@ -11394,6 +11538,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", @@ -11430,6 +11588,16 @@ "d3-timer": "^3.0.1" } }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -11618,7 +11786,7 @@ "license": "ISC" }, "node_modules/wsl-utils": { - "version": "0.3.1", + "version": "0.3.2", "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.1.tgz", "integrity": "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==", "license": "MIT", diff --git a/package.json b/package.json index 04a1ebb..04a2311 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "github-explorer-dashboard", - "version": "0.3.1", + "version": "0.3.2", "private": true, "engines": { "node": ">=22.0.0", @@ -23,6 +23,7 @@ "react-dom": "19.2.4", "react-markdown": "^10.1.0", "recharts": "^3.8.0", + "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.1", "shadcn": "^4.7.0", "tailwind-merge": "^3.6.0", From cfeaee80ad6ad087bbe5ff71199bd2a2be1efd7e Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:13:54 -0400 Subject: [PATCH 3/9] feat: resolve relative image URLs in rendered READMEs Add rehype-raw plugin to parse raw HTML in markdown and a custom img component override that resolves relative image src paths to absolute raw.githubusercontent.com URLs using the repo's default branch. --- src/components/ViewRepo.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/components/ViewRepo.tsx b/src/components/ViewRepo.tsx index 5d8fb5c..22bf6a6 100644 --- a/src/components/ViewRepo.tsx +++ b/src/components/ViewRepo.tsx @@ -18,6 +18,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Badge } from '@/components/ui/badge'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; +import rehypeRaw from 'rehype-raw'; import { motion } from 'framer-motion'; // Common GitHub language colors mapping @@ -236,7 +237,21 @@ export const ViewRepo = () => {

- + { + if (!src || typeof src !== 'string') return null; + const isAbsolute = src.startsWith('http://') || src.startsWith('https://'); + const resolved = isAbsolute + ? src + : `https://raw.githubusercontent.com/${activeRepo.owner.login}/${activeRepo.name}/${activeRepo.default_branch}/${src.replace(/^\.?\//, '')}`; + // eslint-disable-next-line @next/next/no-img-element + return {alt; + }, + }} + > {activeRepoReadme || 'No README available for this repository.'}
From fb1a1b25762eff1960693e778762bab0cef50436 Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:14:25 -0400 Subject: [PATCH 4/9] fix: prevent hydration mismatch from locale-dependent date formatting Replace undefined locale with 'en-US' in toLocaleDateString calls across ViewRepo, ViewUser, and ViewSearch to ensure server and client render identical date strings. --- src/components/ViewRepo.tsx | 4 ++-- src/components/ViewSearch.tsx | 2 +- src/components/ViewUser.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/ViewRepo.tsx b/src/components/ViewRepo.tsx index 22bf6a6..6384014 100644 --- a/src/components/ViewRepo.tsx +++ b/src/components/ViewRepo.tsx @@ -71,13 +71,13 @@ export const ViewRepo = () => { if (!activeRepo) return null; // Date Format Helpers - const createdDate = new Date(activeRepo.created_at).toLocaleDateString(undefined, { + const createdDate = new Date(activeRepo.created_at).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); - const pushedDate = new Date(activeRepo.pushed_at).toLocaleDateString(undefined, { + const pushedDate = new Date(activeRepo.pushed_at).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', diff --git a/src/components/ViewSearch.tsx b/src/components/ViewSearch.tsx index 87fcd74..39949fb 100644 --- a/src/components/ViewSearch.tsx +++ b/src/components/ViewSearch.tsx @@ -224,7 +224,7 @@ export const ViewSearch = () => { - {new Date(item.timestamp).toLocaleDateString(undefined, { + {new Date(item.timestamp).toLocaleDateString('en-US', { month: 'short', day: 'numeric', })} diff --git a/src/components/ViewUser.tsx b/src/components/ViewUser.tsx index f79c037..e877af8 100644 --- a/src/components/ViewUser.tsx +++ b/src/components/ViewUser.tsx @@ -132,7 +132,7 @@ export const ViewUser = () => { if (!activeUser) return null; - const formattedDate = new Date(activeUser.created_at).toLocaleDateString(undefined, { + const formattedDate = new Date(activeUser.created_at).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric', From f9bcb39e7152cc365ea26982e76b47d1cc865b03 Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:14:34 -0400 Subject: [PATCH 5/9] fix: replace Base UI Button with native button to avoid hydration mismatch Base UI's ButtonPrimitive strips the native disabled attribute during SSR but adds it on the client, causing a hydration mismatch. Using a native + From ab8ab262a2fa05e73a9108587323654b695f21cc Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:15:03 -0400 Subject: [PATCH 6/9] fix: use 'en-US' locale for commit date formatting in ViewRepo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Missed in the previous hydration fix pass — the commit timeline date also needs an explicit locale to avoid SSR/CSR mismatch. --- src/components/ViewRepo.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ViewRepo.tsx b/src/components/ViewRepo.tsx index 6384014..473a10b 100644 --- a/src/components/ViewRepo.tsx +++ b/src/components/ViewRepo.tsx @@ -269,7 +269,7 @@ export const ViewRepo = () => { {activeRepoCommits.length > 0 ? (
{activeRepoCommits.map((item) => { - const commitDate = new Date(item.commit.author.date).toLocaleDateString(undefined, { + const commitDate = new Date(item.commit.author.date).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', From 9e9ff8172c5a3eeecc270d1d208053bab82ff78f Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:15:06 -0400 Subject: [PATCH 7/9] docs: update README and AGENTS.md - Bump version badge to v0.3.2 in README - Add rehype-raw to the markdown stack entry - Fix env var name from NEXT_PUBLIC_GITHUB_TOKEN to GITHUB_TOKEN - Add version bump instructions to AGENTS.md --- AGENTS.md | 8 ++++++++ README.md | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e7d274f..13b9281 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,6 +17,14 @@ Always run `npm run lint` after making changes. No typecheck script is configure Do not commit changes unless explicitly asked to. +## Version bump + +When asked to bump the project version, update all three files: + +- `package.json` — `"version"` field +- `package-lock.json` — `"version"` field (both top-level and nested `packages[""]`) +- `README.md` — version badge at the top + All UI text is in English. ## Search API diff --git a/README.md b/README.md index 2ab6ceb..7b2c09d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ High-performance dashboard for exploring GitHub users, repositories, and search results. -**v0.3.0** +**v0.3.2** ## Features @@ -26,14 +26,14 @@ High-performance dashboard for exploring GitHub users, repositories, and search - **State:** Zustand v5 with local persistence - **Animations:** Framer Motion v12 - **Charts:** Recharts v3 (language donut chart) -- **Markdown:** react-markdown + remark-gfm +- **Markdown:** react-markdown + remark-gfm + rehype-raw - **PWA:** Web App Manifest + service worker via Next.js PWA plugin - **Icons:** Lucide React ## Prerequisites - Node.js 20+ -- (Optional) `NEXT_PUBLIC_GITHUB_TOKEN` in `.env.local` to increase GitHub API rate limit +- (Optional) `GITHUB_TOKEN` in `.env.local` to increase GitHub API rate limit ## Commands From e157df5fe23b8170228a03b62714e88bb9affbff Mon Sep 17 00:00:00 2001 From: Marcos Oliveira Date: Sun, 21 Jun 2026 01:28:59 -0400 Subject: [PATCH 8/9] Update README.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b2c09d..cdc7864 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ High-performance dashboard for exploring GitHub users, repositories, and search ## Prerequisites -- Node.js 20+ +- Node.js >=22.0.0 - (Optional) `GITHUB_TOKEN` in `.env.local` to increase GitHub API rate limit ## Commands From 462cf19ab3e062e00e992c8611dd61854794cb24 Mon Sep 17 00:00:00 2001 From: "coderabbitai[bot]" <136622811+coderabbitai[bot]@users.noreply.github.com> Date: Sun, 21 Jun 2026 05:37:28 +0000 Subject: [PATCH 9/9] fix: apply CodeRabbit auto-fixes Fixed 3 file(s) based on 1 unresolved review comment. Co-authored-by: CodeRabbit --- package-lock.json | 30 ++++++++++++++++++++++++++++++ package.json | 1 + src/components/ViewRepo.tsx | 3 ++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index db37a3b..31fcb63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "react-markdown": "^10.1.0", "recharts": "^3.8.0", "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", "remark-gfm": "^4.0.1", "shadcn": "^4.7.0", "tailwind-merge": "^3.6.0", @@ -6165,6 +6166,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", @@ -9787,6 +9803,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-sanitize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-sanitize": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", diff --git a/package.json b/package.json index 04a2311..6cb7a67 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "react-markdown": "^10.1.0", "recharts": "^3.8.0", "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", "remark-gfm": "^4.0.1", "shadcn": "^4.7.0", "tailwind-merge": "^3.6.0", diff --git a/src/components/ViewRepo.tsx b/src/components/ViewRepo.tsx index 473a10b..a7486c7 100644 --- a/src/components/ViewRepo.tsx +++ b/src/components/ViewRepo.tsx @@ -19,6 +19,7 @@ import { Badge } from '@/components/ui/badge'; import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import rehypeRaw from 'rehype-raw'; +import rehypeSanitize from 'rehype-sanitize'; import { motion } from 'framer-motion'; // Common GitHub language colors mapping @@ -239,7 +240,7 @@ export const ViewRepo = () => {
{ if (!src || typeof src !== 'string') return null;