{"_id":"harden-react-markdown","_rev":"13-5f0bff109c7cdb76811914b2f99cba1a","name":"harden-react-markdown","dist-tags":{"latest":"1.1.8"},"versions":{"1.0.0":{"name":"harden-react-markdown","version":"1.0.0","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.0.0","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"d769f3da1346970d5b42cfe31cc69854e8b6456f","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.0.0.tgz","fileCount":5,"integrity":"sha512-mPLTux6b633Pljpi5t+vSFjjt/fCUjqfcgsOnnt2OxUHZM0Dqw55/rv44GpmnY4AVDs2iU6I2O7WqYKccX18EA==","signatures":[{"sig":"MEQCIDdgF65IiZ1zHvfl3zrLWUEXHwueCWQ6hS8G11cZXsW8AiAuc1kAQuqwztgMpUxOQ6rOkwaWpyh4rOcV+hH3e6Knrg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16172},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"ba3fcef0abc4a35d2081c099ff573065527a8501","scripts":{"test":"vitest","build":"tsc","test:ui":"vitest --ui","test:watch":"vitest --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"10.7.0","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"20.14.0","_hasShrinkwrap":false,"packageManager":"pnpm@8.15.7+sha512.c85cd21b6da10332156b1ca2aa79c0a61ee7ad2eb0453b88ab299289e9e8ca93e6091232b25c07cbf61f6df77128d9c849e5c9ac6e44854dbd211c49f3a67adc","devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.0.0_1753930424949_0.6844627794076383","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"harden-react-markdown","version":"1.0.1","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.0.1","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"bdb4abc92fb7d38f181dff63e4416f72fb5a28a0","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.0.1.tgz","fileCount":5,"integrity":"sha512-ghT1nP1uEs+h4CwrQxhvgFexXHmAHWPiN+un34GtIOI78eCEfSSvzArEOMRkB59kmX5qJFdF/AkZndNicF5Xfg==","signatures":[{"sig":"MEYCIQDUSBA9kUW6SrfbhfcIlw5+XoCOQGi/f8Kv2c/3wai7nAIhAIsWj/pST7YmquIyEdmiOWRG2dxaYbM0uduFm/VDyO1C","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16233},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"5435700e48dd079edb87593d21dee1a2ec25f143","scripts":{"test":"vitest","build":"tsc","test:ui":"vitest --ui","test:watch":"vitest --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"10.9.3","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"22.18.0","_hasShrinkwrap":false,"packageManager":"pnpm@8.15.7+sha512.c85cd21b6da10332156b1ca2aa79c0a61ee7ad2eb0453b88ab299289e9e8ca93e6091232b25c07cbf61f6df77128d9c849e5c9ac6e44854dbd211c49f3a67adc","devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.0.1_1754070911134_0.0450843450901941","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"harden-react-markdown","version":"1.0.2","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.0.2","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"fbfcd70e565b9d3b00c5c9fd5002d3b778c2ca3c","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.0.2.tgz","fileCount":5,"integrity":"sha512-NqDXUI231bGvnjdYgidlXCIsya4aqy6ee4Jhf+V60IiRU18yFVSATeEHPdylUAw7Ye637HLLOXxRb4yqp+vSuA==","signatures":[{"sig":"MEUCIBvqZWDYRDvMJoeUXzvOtJuqqHwwFayd6PWpV6ktn9W0AiEA0r6j8ZRKHkeSihYgRqAEa6syCmmLUCyXCJqe7phN6j8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17204},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"6d855a41487713ac76ae65833ba602acd16bf386","scripts":{"test":"vitest","build":"tsc","test:ui":"vitest --ui","test:watch":"vitest --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"10.9.3","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"22.18.0","_hasShrinkwrap":false,"packageManager":"pnpm@8.15.7+sha512.c85cd21b6da10332156b1ca2aa79c0a61ee7ad2eb0453b88ab299289e9e8ca93e6091232b25c07cbf61f6df77128d9c849e5c9ac6e44854dbd211c49f3a67adc","devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.0.2_1754430114174_0.7199239508263915","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"harden-react-markdown","version":"1.0.3","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.0.3","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"a9a8c2b438fb561440deb368319f3670762716f2","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.0.3.tgz","fileCount":5,"integrity":"sha512-Xu5QHbglClzg9BMLx4zjMBEzEW9LqpGOpfypnn6IPVH0gCvM7dRTdXE/CrDsL5sJykwZmn4RRGj+73jyvSDCvg==","signatures":[{"sig":"MEUCIQCE+7xPjEfzo80zVJwfnib50sd9+V6njAp7V0uBToCXpAIgZVfYvUh1U0eNp9y1gdGMJJ9lCiL0MzvfvdRl0vgVgyQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17667},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"f198c8f8e7a5b91de8b0a69d6bab929929d85969","scripts":{"test":"vitest --run","build":"tsc","test:ui":"vitest --ui","test:watch":"vitest --watch","prepublishOnly":"npm run build && npm test"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"10.9.3","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"22.18.0","_hasShrinkwrap":false,"packageManager":"pnpm@8.15.7+sha512.c85cd21b6da10332156b1ca2aa79c0a61ee7ad2eb0453b88ab299289e9e8ca93e6091232b25c07cbf61f6df77128d9c849e5c9ac6e44854dbd211c49f3a67adc","devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.0.3_1754767503888_0.3392887372154556","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"harden-react-markdown","version":"1.0.4","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.0.4","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"972eb13c1793dd45460401c156e2d3a41e88f385","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.0.4.tgz","fileCount":5,"integrity":"sha512-F9JGhMEOPIQjRLL1iwznxXQuJnXuyyhudToQ1ZDFxWz21ZKo1NoD80ymWxAsgGp1RRWunChJQXd9qmp9OMp/yQ==","signatures":[{"sig":"MEUCIQCiUavdD9I7iN2cHwVUg6ZkyGWR7NPhYP26bDj38nEE+gIgJ3ug/lK2L+QQI1j8JnzBFXElIP9KLb5NKCqOYnxghV0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17977},"main":"dist/index.js","_from":"file:harden-react-markdown-1.0.4.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/private/var/folders/1h/2pv55r5s2m7ctn562xnr3b880000gn/T/aff2b1a0dfe121a0ce8f703e22e66475/harden-react-markdown-1.0.4.tgz","_integrity":"sha512-F9JGhMEOPIQjRLL1iwznxXQuJnXuyyhudToQ1ZDFxWz21ZKo1NoD80ymWxAsgGp1RRWunChJQXd9qmp9OMp/yQ==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"10.9.3","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"22.18.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.0.4_1754788884302_0.5817005109082256","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"harden-react-markdown","version":"1.0.5","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.0.5","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"af33f7f8791b84e61dfd7535f5b5522899825998","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.0.5.tgz","fileCount":5,"integrity":"sha512-uN+PdsmySN4gdczqM0DXzltS4dELSO4U/p/QVLiiypyZMBR1CaewgQTI7ZxArFazBoCk7lGRVvYsyxos0VHGNg==","signatures":[{"sig":"MEUCICSvqYCjpXM2bya9IQbuOY2rRhEJm4Jo1upxp1jawHuNAiEAs0EhmCqNnwuNQlSVfjAWpLvx3d/6CVJC3iyI8qQghm0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18266},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"4bb43b7d647b3333961581856d16c7648d03fe0b","scripts":{"test":"vitest --run","build":"tsc","test:ui":"vitest --ui","test:watch":"vitest --watch","prepublishOnly":"pnpm run build && pnpm test"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"10.9.3","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"22.18.0","_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.0.5_1756172064592_0.4835542593893618","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"harden-react-markdown","version":"1.1.2","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.1.2","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"a25dd4acba08aeb957ec748d65d2d3e2fdeb24e8","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.2.tgz","fileCount":5,"integrity":"sha512-4VRzZUz/2oV07ugbEhQHG8elHhqqqiYHjaU4Y5Y3pf7+0kzVDJhcdAS/3SdAOKsAscT+YoPhiEMmTUnVktjDrw==","signatures":[{"sig":"MEYCIQDj9Sjx7aHa0jfG+dwHyok1ZxuL5sXnQEaUS48bQQxPZwIhAL44RH0dsj2gYouLb7AyNF+to1JacJto3hG1OmkQKQfS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12688},"main":"dist/index.js","_from":"file:harden-react-markdown-1.1.2.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","check":"tsc --noEmit","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/tmp/d5d1407282fcc09479687c65ec123c6e/harden-react-markdown-1.1.2.tgz","_integrity":"sha512-4VRzZUz/2oV07ugbEhQHG8elHhqqqiYHjaU4Y5Y3pf7+0kzVDJhcdAS/3SdAOKsAscT+YoPhiEMmTUnVktjDrw==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"11.6.0","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"24.8.0","dependencies":{"rehype-harden":"1.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.1.2_1758740042414_0.7330951166076964","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"harden-react-markdown","version":"1.1.3","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.1.3","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"73f13302404f01573ac988fa9b9d2ef1d04b4d65","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.3.tgz","fileCount":5,"integrity":"sha512-r27mosnybHxdtXkzC/+KgZfyof8TH/vLdYypYUACkAV6D1gRauW8jcZBUfxKzVdctLcw8BD8AP/0qKrKkLXIWA==","signatures":[{"sig":"MEYCIQDjL0s7IYI4OntqKdJDwGR3WwkSbeV1iNepf+2Z6aWo/QIhANVDS5ryUye+2frkg7xBUnZ/kpgo8FItY03wkkFN7i+p","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":12688},"main":"dist/index.js","_from":"file:harden-react-markdown-1.1.3.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","check":"tsc --noEmit","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/tmp/dd5b61b6a6c0bec50c8e71778db60fe8/harden-react-markdown-1.1.3.tgz","_integrity":"sha512-r27mosnybHxdtXkzC/+KgZfyof8TH/vLdYypYUACkAV6D1gRauW8jcZBUfxKzVdctLcw8BD8AP/0qKrKkLXIWA==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"11.6.0","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"24.9.0","dependencies":{"rehype-harden":"1.1.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.1.3_1760050576687_0.4195479522343817","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"harden-react-markdown","version":"1.1.4","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.1.4","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"62deeb7f1b882de2d1bec4e59a17075d04d0ad97","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.4.tgz","fileCount":5,"integrity":"sha512-7rYpMoMdEf3LjEnKGn2T5RyqQxqVm/OW188ajvfkGGaZe0TDNln88k92trw38e305RVA/iwhXmdzVb53BavLOA==","signatures":[{"sig":"MEUCIQDf2Fdqsq3+OJGojKp14czaN1xrqqAmJa4Gqa++KzmiXAIgEOrn4LGha5b0I3FbbdPyXpntlGrfe41UCkLrDuHivYw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14648},"main":"dist/index.js","_from":"file:harden-react-markdown-1.1.4.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","check":"tsc --noEmit","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/tmp/79d07a45305a4012890f7eea5304295f/harden-react-markdown-1.1.4.tgz","_integrity":"sha512-7rYpMoMdEf3LjEnKGn2T5RyqQxqVm/OW188ajvfkGGaZe0TDNln88k92trw38e305RVA/iwhXmdzVb53BavLOA==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"11.6.0","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"24.9.0","dependencies":{"rehype-harden":"1.1.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.1.4_1760115143917_0.269723588802363","host":"s3://npm-registry-packages-npm-production"}},"1.1.5":{"name":"harden-react-markdown","version":"1.1.5","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.1.5","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"17ab98a6067143c9af3252799cc7b933f913e33a","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.5.tgz","fileCount":5,"integrity":"sha512-u0OFAPakA/FE9ZCOgUakvB55ygfHiK0grQgKdztcTe73d6Dz/6Flz04hv6pPq7zzZYAgjeEZQwR2zQYifC0NVQ==","signatures":[{"sig":"MEUCIQDDk8e977OEidqdaaTwO16OHVwie5FqwffaDxHsemTAfQIgcV4xnscV2qu7T1pWHQX9kZuOAzIGUK6esIhTK6Z9TeI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14648},"main":"dist/index.js","_from":"file:harden-react-markdown-1.1.5.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","check":"tsc --noEmit","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/tmp/70c6da67bfc90e83834312141c389950/harden-react-markdown-1.1.5.tgz","_integrity":"sha512-u0OFAPakA/FE9ZCOgUakvB55ygfHiK0grQgKdztcTe73d6Dz/6Flz04hv6pPq7zzZYAgjeEZQwR2zQYifC0NVQ==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"11.6.0","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"24.9.0","dependencies":{"rehype-harden":"1.1.5"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.1.5_1760117759181_0.44095400159713205","host":"s3://npm-registry-packages-npm-production"}},"1.1.6":{"name":"harden-react-markdown","version":"1.1.6","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.1.6","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"a388f1706c9ccc0883dac381dab7d38ff9126a58","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.6.tgz","fileCount":5,"integrity":"sha512-qA5Kcpz9QSFm9OMKyjwSU5DneHM9OoyRMlczpsMjTnbDQ9PlQAdsCFWMwLRwqWX9BcEn4sqltx7s0tEbuGpIxg==","signatures":[{"sig":"MEYCIQCgrKBHadLRg01E0KU6kvdgMatXjGckSsNQW212pdvOQQIhAJ73i81NJqH7GJVLxhUtI2MgNvbp9tl4yZyQhlR+A/5L","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16880},"main":"dist/index.js","_from":"file:harden-react-markdown-1.1.6.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","check":"tsc --noEmit","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/tmp/45ecb0e71f62e695e9035868975fbf13/harden-react-markdown-1.1.6.tgz","_integrity":"sha512-qA5Kcpz9QSFm9OMKyjwSU5DneHM9OoyRMlczpsMjTnbDQ9PlQAdsCFWMwLRwqWX9BcEn4sqltx7s0tEbuGpIxg==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"11.6.2","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"24.11.1","dependencies":{"rehype-raw":"^7.0.0","rehype-harden":"1.1.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.1.6_1764372207710_0.2925337632933369","host":"s3://npm-registry-packages-npm-production"}},"1.1.7":{"name":"harden-react-markdown","version":"1.1.7","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","_id":"harden-react-markdown@1.1.7","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"homepage":"https://github.com/vercel/harden-react-markdown#readme","bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"dist":{"shasum":"a020b50a733ccc8ffe1fde4016b21074a02ff504","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.7.tgz","fileCount":5,"integrity":"sha512-hL3j/DTtNof9MRT38VgTujKbiET+pF8EzS6oC1T8XahR0+uIYo6lUGmYmw3sQ6VAEB6WQsBHRIc7oD/7LAbRzQ==","signatures":[{"sig":"MEUCIQDNendoOpyAeNFNSi3WNfJ7zYDTM5cJE54dJJ96URYtyAIgOggrP/BYcTbF3LkRoV5UqsaXOK0WH1//044x09i3rWk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16880},"main":"dist/index.js","_from":"file:harden-react-markdown-1.1.7.tgz","types":"dist/index.d.ts","scripts":{"test":"vitest --run","build":"tsc","check":"tsc --noEmit","test:ui":"vitest --ui","test:watch":"vitest --watch"},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"_resolved":"/tmp/724c2c0dab7384db242c0058074fa7d3/harden-react-markdown-1.1.7.tgz","_integrity":"sha512-hL3j/DTtNof9MRT38VgTujKbiET+pF8EzS6oC1T8XahR0+uIYo6lUGmYmw3sQ6VAEB6WQsBHRIc7oD/7LAbRzQ==","repository":{"url":"git+https://github.com/vercel/harden-react-markdown.git","type":"git"},"_npmVersion":"11.6.2","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","directories":{},"_nodeVersion":"24.11.1","dependencies":{"rehype-raw":"^7.0.0","rehype-harden":"1.1.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^7.0.6","jsdom":"^26.1.0","react":"^19.1.0","vitest":"^3.2.4","react-dom":"^19.1.0","typescript":"^5","@types/node":"^20","@types/react":"^19","react-markdown":"^10.1.0","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.6.4"},"peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/harden-react-markdown_1.1.7_1765230786493_0.4267969857609675","host":"s3://npm-registry-packages-npm-production"}},"1.1.8":{"name":"harden-react-markdown","version":"1.1.8","description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","main":"dist/index.js","types":"dist/index.d.ts","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"author":{"name":"Your Name"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/vercel/harden-react-markdown.git"},"bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"homepage":"https://github.com/vercel/harden-react-markdown#readme","peerDependencies":{"react":">=16.8.0","react-markdown":">=9.0.0"},"dependencies":{"rehype-raw":"^7.0.0","rehype-harden":"1.1.8"},"devDependencies":{"@testing-library/jest-dom":"^6.6.4","@testing-library/react":"^16.3.0","@types/node":"^20","@types/react":"^19","@types/react-dom":"^19","@vitejs/plugin-react":"^4.7.0","jsdom":"^26.1.0","react":"^19.1.0","react-dom":"^19.1.0","react-markdown":"^10.1.0","typescript":"^5","vite":"^7.0.6","vitest":"^3.2.4"},"publishConfig":{"access":"public"},"scripts":{"check":"tsc --noEmit","build":"tsc","test":"vitest --run","test:watch":"vitest --watch","test:ui":"vitest --ui"},"_id":"harden-react-markdown@1.1.8","_integrity":"sha512-jEGn7TSTqRhXHtadEnwgztDWfgziTKHlPNg6FGIwoOHdxqhlzCxuXcXystO+ZUTv1fy8S0gNg7kxZ83Av5owjQ==","_resolved":"/tmp/e8cdd11ab688535864d2d324125c876f/harden-react-markdown-1.1.8.tgz","_from":"file:harden-react-markdown-1.1.8.tgz","_nodeVersion":"24.13.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-jEGn7TSTqRhXHtadEnwgztDWfgziTKHlPNg6FGIwoOHdxqhlzCxuXcXystO+ZUTv1fy8S0gNg7kxZ83Av5owjQ==","shasum":"7ba861f22d7afb766b74b1d3dab7621d168bb62b","tarball":"https://registry.npmjs.org/harden-react-markdown/-/harden-react-markdown-1.1.8.tgz","fileCount":5,"unpackedSize":18539,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDdb7MMRKgy+9W2cc8wvgcP6dwc1YhgzPIxhYmSsvm0JwIhAOdZHLxxPTGaVci166SikWfUCLY1GmKV48QApxuykLTp"}]},"_npmUser":{"name":"cramforce","email":"malte.ubl@gmail.com"},"directories":{},"maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/harden-react-markdown_1.1.8_1771470342214_0.5246208997921837"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-31T02:53:44.948Z","modified":"2026-02-19T03:05:42.460Z","1.0.0":"2025-07-31T02:53:45.164Z","1.0.1":"2025-08-01T17:55:11.335Z","1.0.2":"2025-08-05T21:41:54.396Z","1.0.3":"2025-08-09T19:25:04.098Z","1.0.4":"2025-08-10T01:21:24.497Z","1.0.5":"2025-08-26T01:34:24.839Z","1.1.2":"2025-09-24T18:54:02.600Z","1.1.3":"2025-10-09T22:56:16.904Z","1.1.4":"2025-10-10T16:52:24.106Z","1.1.5":"2025-10-10T17:35:59.363Z","1.1.6":"2025-11-28T23:23:27.882Z","1.1.7":"2025-12-08T21:53:06.632Z","1.1.8":"2026-02-19T03:05:42.342Z"},"bugs":{"url":"https://github.com/vercel/harden-react-markdown/issues"},"author":{"name":"Your Name"},"license":"MIT","homepage":"https://github.com/vercel/harden-react-markdown#readme","keywords":["react","markdown","security","url-filtering","xss-protection","react-markdown"],"repository":{"type":"git","url":"git+https://github.com/vercel/harden-react-markdown.git"},"description":"A security-focused wrapper for react-markdown that filters URLs based on allowed prefixes","maintainers":[{"name":"cramforce","email":"malte.ubl@gmail.com"}],"readme":"# harden-react-markdown\n\nA wrapper for [react-markdown](https://www.npmjs.com/package/react-markdown) that ensures that untrusted\nmarkdown does not contain images from and links to unexpected origins.\n\nThis is particularly important for markdown returned from [LLMs in AI agents which might have been subject to prompt\ninjection](https://vercel.com/blog/building-secure-ai-agents).\n\n## Secure prefixes\n\nThis package validates URL prefixes and URL origins. Prefix allow-lists can be circumvented\nwith open redirects, so make sure to make the prefixes are specific enough to avoid such attacks.\n\nE.g. it is more secure to allow `https://example.com/images/` than it is to allow all of\n`https://example.com/` which may contain open redirects.\n\nAdditionally, URLs may contain path traversal like `/../`. This package does not resolve these.\nIt is your responsibility that your web server does not allow such traversal.\n\n## Features\n\n- 🔒 **URL Filtering**: Blocks links and images that don't match allowed URL prefixes\n- 🔧 **Drop-in Replacement**: Works with any react-markdown compatible component\n\n## Installation\n\n```bash\nnpm install harden-react-markdown react react-markdown\n# or\nyarn add harden-react-markdown react react-markdown\n# or\npnpm add harden-react-markdown react react-markdown\n```\n\n## Quick Start\n\n```tsx\nimport React from \"react\";\nimport ReactMarkdown from \"react-markdown\";\nimport hardenReactMarkdown from \"harden-react-markdown\";\n\n// Create a hardened version of ReactMarkdown\nconst HardenedMarkdown = hardenReactMarkdown(ReactMarkdown);\n\nfunction MyComponent() {\n  const markdown = `\n# My Document\n[Safe Link](https://github.com/user/repo)\n[Blocked Link](https://malicious-site.com)\n![Safe Image](https://via.placeholder.com/150)\n![Blocked Image](https://evil.com/tracker.gif)\n  `;\n\n  return (\n    <HardenedMarkdown\n      defaultOrigin=\"https://mysite.com\"\n      allowedLinkPrefixes={[\"https://github.com/\", \"https://docs.\"]}\n      allowedImagePrefixes={[\"https://via.placeholder.com/\", \"/\"]}\n    >\n      {markdown}\n    </HardenedMarkdown>\n  );\n}\n```\n\n## API\n\n### `hardenReactMarkdown(MarkdownComponent)`\n\nCreates a hardened version of any react-markdown compatible component.\n\n#### Parameters\n\n- `MarkdownComponent`: A React component that accepts `Options` from react-markdown\n\n#### Returns\n\nA new component with enhanced security that accepts all original props plus:\n\n### Props\n\n#### `defaultOrigin?: string`\n\n- The origin to resolve relative URLs against\n- Required when `allowedLinkPrefixes` or `allowedImagePrefixes` are provided\n- Example: `\"https://mysite.com\"`\n\n#### `allowedLinkPrefixes?: string[]`\n\n- Array of URL prefixes that are allowed for links\n- Links not matching these prefixes will be blocked and shown as `[blocked]`\n- Use `\"*\"` to allow all URLs (disables filtering. However, `javascript:` and `data:` URLs are always disallowed)\n- Default: `[]` (blocks all links)\n- Example: `['https://github.com/', 'https://docs.example.com/']` or `['*']`\n\n#### `allowedImagePrefixes?: string[]`\n\n- Array of URL prefixes that are allowed for images\n- Images not matching these prefixes will be blocked and shown as placeholders\n- Use `\"*\"` to allow all URLs (disables filtering. However, `javascript:` and `data:` URLs are always disallowed unless `allowDataImages` is enabled)\n- Default: `[]` (blocks all images)\n- Example: `['https://via.placeholder.com/', '/']` or `['*']`\n\n#### `allowDataImages?: boolean`\n\n- When set to `true`, allows `data:image/*` URLs (base64-encoded images) in image sources\n- This is useful for scenarios where images are embedded directly in markdown (e.g., documents converted from PDF or .docx)\n- Only `data:image/*` URLs are allowed; other `data:` URLs (like `data:text/html`) remain blocked for security\n- `data:` URLs are never allowed in links, regardless of this setting\n- Default: `false` (blocks all data: URLs)\n- Example: `true`\n\n#### `allowedProtocols?: string[]`\n\n- Array of custom URL protocols that are allowed in links\n- Useful for deep links to applications (e.g., `tel:`, `mailto:`, `postman:`, `vscode:`, `slack:`)\n- Use `\"*\"` to allow all protocols that can be parsed as valid URLs\n- Dangerous protocols (`javascript:`, `data:`, `file:`, `vbscript:`) are **always blocked** regardless of this setting\n- Default: `[]` (only allows built-in safe protocols: `https:`, `http:`, `mailto:`, `irc:`, `ircs:`, `xmpp:`, `blob:`)\n- Example: `['tel:', 'postman:', 'vscode:']` or `['*']`\n\n#### `linkBlockPolicy?: BlockPolicyType`\n\n- Controls how blocked links are handled\n- `\"indicator\"` (default): Renders as plain text with `[blocked]` suffix and the blocked URL in a title attribute\n- `\"text-only\"`: Renders just the link text without any indicator or URL\n- `\"remove\"`: Removes the blocked link entirely from the output\n\n#### `imageBlockPolicy?: BlockPolicyType`\n\n- Controls how blocked images are handled\n- `\"indicator\"` (default): Renders as a placeholder span with `[Image blocked: {alt text}]`\n- `\"text-only\"`: Renders just the alt text (images with no alt text are removed)\n- `\"remove\"`: Removes the blocked image entirely from the output\n\nAll other props are passed through to the wrapped markdown component.\n\n## Examples\n\n### Basic Usage with Default Blocking\n\n```tsx\nconst HardenedMarkdown = hardenReactMarkdown(ReactMarkdown);\n\n// Blocks all external links and images by default\n<HardenedMarkdown>{markdownContent}</HardenedMarkdown>;\n```\n\n### Allow Specific Domains\n\n```tsx\n<HardenedMarkdown\n  defaultOrigin=\"https://mysite.com\"\n  allowedLinkPrefixes={[\n    \"https://github.com/\",\n    \"https://docs.github.com/\",\n    \"https://www.npmjs.com/\",\n  ]}\n  allowedImagePrefixes={[\n    \"https://via.placeholder.com/\",\n    \"https://images.unsplash.com/\",\n    \"/\", // Allow relative images\n  ]}\n>\n  {markdownContent}\n</HardenedMarkdown>\n```\n\n### Relative URL Handling\n\n```tsx\n<HardenedMarkdown\n  defaultOrigin=\"https://mysite.com\"\n  allowedLinkPrefixes={[\"https://mysite.com/\"]}\n  allowedImagePrefixes={[\"https://mysite.com/\"]}\n>\n  {`\n  [Relative Link](/internal-page)\n  ![Relative Image](/images/logo.png)\n  `}\n</HardenedMarkdown>\n```\n\n### Allow All URLs (Wildcard)\n\n```tsx\n<HardenedMarkdown allowedLinkPrefixes={[\"*\"]} allowedImagePrefixes={[\"*\"]}>\n  {`\n  [Any Link](https://anywhere.com/link)\n  ![Any Image](https://untrusted-site.com/image.jpg)\n  `}\n</HardenedMarkdown>\n```\n\n**Note**: Using `\"*\"` disables URL filtering entirely. Only use this when you trust the markdown source.\n\n### Allow Base64 Images\n\n```tsx\n<HardenedMarkdown\n  defaultOrigin=\"https://mysite.com\"\n  allowedImagePrefixes={[\"https://mysite.com/\"]}\n  allowDataImages={true}\n>\n  {`\n  ![Base64 Image](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==)\n  ![Regular Image](https://mysite.com/image.png)\n  `}\n</HardenedMarkdown>\n```\n\n**Note**: This is particularly useful when converting documents from formats like PDF or .docx where images are embedded as base64. Only `data:image/*` URLs are allowed; other data: URLs remain blocked for security.\n\n### Custom Protocol Support\n\nEnable custom protocols for deep linking to applications and services:\n\n```tsx\n<HardenedMarkdown allowedProtocols={[\"tel:\", \"mailto:\", \"postman:\", \"vscode:\", \"slack:\"]}>\n  {`\n  [Call us](tel:+1234567890)\n  [Email support](mailto:support@example.com)\n  [Open in Postman](postman://open/collection)\n  [View in VS Code](vscode://file/path/to/file.ts)\n  [Join Slack](slack://channel?id=C123456)\n  `}\n</HardenedMarkdown>\n```\n\n**Common use cases:**\n- **`tel:`** - Phone number links that open the dialer on mobile devices\n- **`mailto:`** - Email links (allowed by default, but shown here for completeness)\n- **`sms:`** - SMS/text message links\n- **`postman:`**, **`vscode:`**, **`slack:`** - Deep links to desktop applications\n- **Custom app protocols** - Links to your own Electron or native applications\n\nYou can also use the wildcard to allow any custom protocol:\n\n```tsx\n<HardenedMarkdown allowedProtocols={[\"*\"]}>\n  {`[Custom Protocol Link](customapp://action)`}\n</HardenedMarkdown>\n```\n\n**Security Note**: Even with `allowedProtocols={[\"*\"]}`, dangerous protocols like `javascript:`, `data:`, `file:`, and `vbscript:` are **always blocked** for security. Custom protocols are safe because they trigger OS-level protocol handlers and don't execute in the browser context.\n\n### Block Policies\n\nControl how blocked content is handled instead of the default `[blocked]` indicator:\n\n```tsx\n<HardenedMarkdown\n  defaultOrigin=\"https://mysite.com\"\n  allowedLinkPrefixes={[\"https://trusted.com/\"]}\n  allowedImagePrefixes={[\"https://trusted.com/\"]}\n  linkBlockPolicy=\"text-only\" // Show link text only, no [blocked] indicator\n  imageBlockPolicy=\"remove\" // Remove blocked images entirely\n>\n  {markdownContent}\n</HardenedMarkdown>\n```\n\nAvailable policies: `\"indicator\"` (default), `\"text-only\"`, `\"remove\"`.\n\n### Custom Components\n\n```tsx\nconst CustomMarkdown = (props) => (\n  <div className=\"custom-wrapper\">\n    <ReactMarkdown {...props} />\n  </div>\n);\n\nconst HardenedCustomMarkdown = hardenReactMarkdown(CustomMarkdown);\n\n<HardenedCustomMarkdown\n  defaultOrigin=\"https://mysite.com\"\n  allowedLinkPrefixes={[\"https://trusted.com/\"]}\n>\n  {markdownContent}\n</HardenedCustomMarkdown>;\n```\n\n## Security Features\n\n### URL Filtering\n\n- **Links**: Filters `href` attributes in `<a>` elements\n- **Images**: Filters `src` attributes in `<img>` elements\n- **Relative URLs**: Properly resolves and validates relative URLs against `defaultOrigin`\n- **Path Traversal Protection**: Normalizes URLs to prevent `../` attacks\n- **Wildcard Support**: Use `\"*\"` prefix to disable filtering (only when markdown is trusted)\n- **Prefix Matching**: Validates that URLs start with allowed prefixes and have matching origins\n\n### Blocked Content Handling\n\nBehavior is configurable per element type via `linkBlockPolicy` and `imageBlockPolicy`:\n\n- **`\"indicator\"`** (default): Blocked links show a `[blocked]` suffix; blocked images show `[Image blocked: {alt}]`\n- **`\"text-only\"`**: Outputs just the link text or image alt text with no indicator\n- **`\"remove\"`**: Removes blocked elements entirely from the output\n\n### Attack Prevention\n\n- **XSS Prevention**: Blocks `javascript:`, `data:`, `vbscript:`, `file:` and other dangerous protocols (always, regardless of configuration)\n- **Redirect Protection**: Prevents unauthorized redirects to malicious sites\n- **Tracking Prevention**: Blocks unauthorized image tracking pixels\n- **Domain Spoofing**: Validates full URLs, not just domains\n- **Custom Protocols**: Optional support for custom protocols (e.g., `tel:`, `postman:`, `vscode:`) with explicit opt-in via `allowedProtocols`\n\n## TypeScript Support\n\nFull TypeScript support with strict type checking:\n\n```tsx\n// Type-safe component creation\nconst HardenedMarkdown = hardenReactMarkdown(ReactMarkdown);\n\n// Inferred prop types include both react-markdown Options and security options\ntype Props = Parameters<typeof HardenedMarkdown>[0];\n\n// Works with custom markdown components\nconst CustomMarkdown = (props: Options & { customProp?: string }) => (\n  <ReactMarkdown {...props} />\n);\n\nconst HardenedCustom = hardenReactMarkdown(CustomMarkdown);\n// Props now include customProp + security options\n```\n\n## Testing\n\nThe package includes comprehensive tests covering:\n\n- Basic markdown rendering\n- URL filtering for links and images\n- Relative URL handling\n- Security bypass prevention\n- Edge cases and malformed URLs\n- TypeScript type safety\n\nRun tests:\n\n```bash\nnpm test\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details.\n\n## Security\n\nIf you discover a security vulnerability, please send an e-mail to <security@vercel.com>.\n","readmeFilename":"README.md"}