{"_id":"@rigelbuild/solid-markdown","name":"@rigelbuild/solid-markdown","dist-tags":{"next":"3.0.0-rc.0","latest":"3.0.0-rc.0"},"versions":{"3.0.0-rc.0":{"name":"@rigelbuild/solid-markdown","version":"3.0.0-rc.0","publishConfig":{"access":"public"},"description":"Markdown renderer for solid-js","license":"MIT","keywords":["remark","unified","markdown","commonmark","gfm","ast","solid","solid-js","solid-js-component","component"],"author":"Andi Rosca <andi23rosca@gmail.com>","contributors":[{"name":"Andi Rosca","url":"https://github.com/andi23rosca"},{"name":"High1","url":"https://github.com/high1"},{"name":"Patrick Heneise","url":"https://github.com/patrickheneise"}],"repository":{"type":"git","url":"git+https://github.com/RigelBuild/solid-markdown.git"},"homepage":"https://github.com/RigelBuild/solid-markdown#readme","bugs":{"url":"https://github.com/RigelBuild/solid-markdown/issues"},"private":false,"sideEffects":false,"type":"module","main":"./dist/server.js","module":"./dist/server.js","types":"./dist/index.d.ts","browser":{"./dist/server.js":"./dist/index.js"},"exports":{"worker":{"solid":"./dist/index.jsx","import":{"types":"./dist/index.d.ts","default":"./dist/server.js"}},"browser":{"solid":"./dist/index.jsx","development":{"import":{"types":"./dist/index.d.ts","default":"./dist/dev.js"}},"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"deno":{"solid":"./dist/index.jsx","import":{"types":"./dist/index.d.ts","default":"./dist/server.js"}},"node":{"solid":"./dist/index.jsx","import":{"types":"./dist/index.d.ts","default":"./dist/server.js"}},"solid":"./dist/index.jsx","development":{"import":{"types":"./dist/index.d.ts","default":"./dist/dev.js"}},"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"typesVersions":{},"scripts":{"dev":"vite serve dev","build":"bun run build.ts && bun run smoke","smoke":"bun run scripts/smoke-dist.ts","test":"bun run test:client && bun run test:ssr","test:client":"SOLID_GENERATE=dom bun --conditions=browser --conditions=development test test/client.test.tsx","test:ssr":"SOLID_GENERATE=ssr bun --conditions=development test test/server.test.tsx","typecheck":"tsc --noEmit","lint":"biome check .","format":"biome format --write ."},"dependencies":{"devlop":"^1.1.0","hast-util-to-jsx-runtime":"^2.3.6","html-url-attributes":"^3.0.1","remark-parse":"^11.0.0","remark-rehype":"^11.1.2","unified":"^11.0.5","unist-util-visit":"^5.1.0","vfile":"^6.0.3"},"peerDependencies":{"@solidjs/web":"^2.0.0-rc.0","solid-js":"^2.0.0-rc.0"},"devDependencies":{"@babel/core":"^7.28.4","@babel/preset-typescript":"^7.27.1","@biomejs/biome":"1.9.4","@happy-dom/global-registrator":"^20.0.0","@solidjs/testing-library":"1.0.0-beta.2","@solidjs/web":"2.0.0-rc.0","@types/bun":"^1.4.0","@types/hast":"^3.0.4","@types/unist":"^3.0.3","babel-preset-solid":"2.0.0-rc.0","rehype-raw":"^7.0.0","rehype-starry-night":"^2.2.0","remark-gfm":"^4.0.1","remark-toc":"^9.0.0","solid-js":"2.0.0-rc.0","typescript":"^5.9.3","vite":"^7.2.4","vite-plugin-solid":"3.0.0-next.27"},"engines":{"node":">=18"},"_id":"@rigelbuild/solid-markdown@3.0.0-rc.0","_integrity":"sha512-jCo2Hjb0Hj67mVvYGt8Ra3l/4s+p7KnHPF+9Vm8Py/p2HbskiwAc57cSFssn6sBbizqBbZfqR6B6trG38pBhaw==","_nodeVersion":"24.3.0","_npmVersion":"10.8.3","shasum":"1c41550797f269b68a7e2ebbe79982029ee1e1fe","dist":{"integrity":"sha512-jCo2Hjb0Hj67mVvYGt8Ra3l/4s+p7KnHPF+9Vm8Py/p2HbskiwAc57cSFssn6sBbizqBbZfqR6B6trG38pBhaw==","shasum":"1c41550797f269b68a7e2ebbe79982029ee1e1fe","tarball":"https://registry.npmjs.org/@rigelbuild/solid-markdown/-/solid-markdown-3.0.0-rc.0.tgz","fileCount":10,"unpackedSize":50925,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGcwOjMj/D5vlOyjp9aUYkWFmzl0GFA3xYG7NPETg7mSAiAFCd5SvsqhtQ84KKgQjXaLgZTvrNzDcbo8qWhzkwqeMQ=="}]},"_npmUser":{"name":"zireael13","email":"mattwilki17@gmail.com"},"directories":{},"maintainers":[{"name":"zireael13","email":"mattwilki17@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/solid-markdown_3.0.0-rc.0_1787406604069_0.7314420528170242"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-22T13:50:03.894Z","3.0.0-rc.0":"2026-08-22T13:50:04.232Z","modified":"2026-08-22T13:50:04.521Z"},"maintainers":[{"name":"zireael13","email":"mattwilki17@gmail.com"}],"description":"Markdown renderer for solid-js","homepage":"https://github.com/RigelBuild/solid-markdown#readme","keywords":["remark","unified","markdown","commonmark","gfm","ast","solid","solid-js","solid-js-component","component"],"repository":{"type":"git","url":"git+https://github.com/RigelBuild/solid-markdown.git"},"contributors":[{"name":"Andi Rosca","url":"https://github.com/andi23rosca"},{"name":"High1","url":"https://github.com/high1"},{"name":"Patrick Heneise","url":"https://github.com/patrickheneise"}],"author":"Andi Rosca <andi23rosca@gmail.com>","bugs":{"url":"https://github.com/RigelBuild/solid-markdown/issues"},"license":"MIT","readme":"<p>\n  <img width=\"100%\" src=\"https://assets.solidjs.com/banner?type=solid-markdown&background=tiles&project=%20\" alt=\"solid-markdown\">\n</p>\n\n# `solid-markdown`\n\nRender markdown to Solid components.\n\n`solid-markdown` now tracks the `react-markdown` 10.x API closely and keeps the rendering pipeline upstream-aligned while adapting the JSX output to Solid.\n\n## Why this update matters\n\nThis package is now a real Solid port of modern `react-markdown`, not a compatibility wrapper around older behavior. The public API matches upstream concepts such as `components`, `remarkRehypeOptions`, `urlTransform`, and async plugin support, while Solid gets one extra client-side helper: `MarkdownResource`.\n\n## Installation\n\n```bash\nbun add @rigelbuild/solid-markdown\n```\n\n## Usage\n\n```tsx\nimport Markdown from \"@rigelbuild/solid-markdown\";\nimport remarkGfm from \"remark-gfm\";\n\nconst markdown = `\n# This is a title\n\n- here's\n- a\n- list\n`;\n\nexport default function App() {\n\treturn <Markdown remarkPlugins={[remarkGfm]}>{markdown}</Markdown>;\n}\n```\n\n## API reference\n\n| Export | Type | Purpose |\n| --- | --- | --- |\n| `Markdown` | component | Synchronous markdown renderer. |\n| `MarkdownAsync` | function | Async/server renderer for async unified plugins. |\n| `MarkdownResource` | component | Solid client wrapper for async plugin pipelines. |\n| `defaultUrlTransform` | function | Default URL sanitizer used for links and images. |\n| `AllowElement` | type | Per-element allow/deny callback. |\n| `Components` | type | Custom tag-to-component overrides. |\n| `ExtraProps` | type | Extra props passed to custom components (`node`). |\n| `Options` | type | Shared renderer options. |\n| `MarkdownResourceOptions` | type | `Options` plus `fallback`. |\n| `UrlTransform` | type | URL rewrite/sanitization hook. |\n\n### `Markdown`\n\nSynchronous markdown renderer.\n\n```tsx\nimport Markdown from \"@rigelbuild/solid-markdown\";\nimport remarkGfm from \"remark-gfm\";\n\n<Markdown remarkPlugins={[remarkGfm]}>{value()}</Markdown>;\n```\n\n### `MarkdownAsync`\n\nAsync/server helper for async unified plugins.\n\n```tsx\nimport { MarkdownAsync } from \"@rigelbuild/solid-markdown\";\nimport rehypeStarryNight from \"rehype-starry-night\";\n\nconst content = await MarkdownAsync({\n\tchildren: \"```js\\nconsole.log(3.14)\\n```\",\n\trehypePlugins: [rehypeStarryNight],\n});\n\nreturn <div class=\"preview\">{content}</div>;\n```\n\n### `MarkdownResource`\n\nSolid-native client wrapper for async plugins.\n\n```tsx\nimport { MarkdownResource } from \"@rigelbuild/solid-markdown\";\nimport rehypeStarryNight from \"rehype-starry-night\";\n\n<MarkdownResource\n\tchildren={value()}\n\tfallback={<p>Rendering…</p>}\n\trehypePlugins={[rehypeStarryNight]}\n/>;\n```\n\n### `defaultUrlTransform`\n\nBy default, unsafe protocols such as `javascript:` are removed while standard URLs, fragments, and paths are preserved.\n\n```tsx\nimport Markdown, { defaultUrlTransform } from \"@rigelbuild/solid-markdown\";\n\n<Markdown\n\turlTransform={(url, key, node) => {\n\t\tconst safe = defaultUrlTransform(url);\n\t\tif (!safe) return safe;\n\t\treturn key === \"href\" && node.tagName === \"a\" ? `/out?url=${encodeURIComponent(safe)}` : safe;\n\t}}\n>\n\t{\"[OpenAI](https://openai.com)\"}\n</Markdown>;\n```\n\n## Options\n\nSupported options match upstream `react-markdown` 10.x semantics:\n\n| Option | Purpose |\n| --- | --- |\n| `allowElement` | Decide per HAST element whether it should render. |\n| `allowedElements` | Allowlist tag names. |\n| `children` | Markdown source string. `null` and `undefined` render nothing. |\n| `components` | Override specific HTML tags with Solid components or tag names. |\n| `disallowedElements` | Blocklist tag names. |\n| `rehypePlugins` | Rehype plugins applied after markdown is converted to HAST. |\n| `remarkPlugins` | Remark plugins applied while parsing markdown. |\n| `remarkRehypeOptions` | Extra `remark-rehype` options merged with the safe defaults used by upstream. |\n| `skipHtml` | Ignore raw HTML in the markdown source. |\n| `unwrapDisallowed` | Keep children of removed nodes instead of dropping the whole subtree. |\n| `urlTransform` | Rewrite or sanitize link and image URLs. |\n\n## Components\n\nCustom components receive normal Solid intrinsic props plus `node`.\n\n```tsx\nimport Markdown, { type Components } from \"@rigelbuild/solid-markdown\";\n\nconst components: Components = {\n\tcode(props) {\n\t\treturn <code data-tag={props.node?.tagName}>{props.children}</code>;\n\t},\n};\n\n<Markdown components={components}>{\"`example`\"}</Markdown>;\n```\n\n## Migration\n\n### Default import\n\nBefore:\n\n```tsx\nimport { SolidMarkdown } from \"@rigelbuild/solid-markdown\";\n\n<SolidMarkdown children={markdown} />;\n```\n\nAfter:\n\n```tsx\nimport Markdown from \"@rigelbuild/solid-markdown\";\n\n<Markdown>{markdown}</Markdown>;\n```\n\n### Wrapper ownership\n\nBefore:\n\n```tsx\n<Markdown class=\"markdown-body\">{markdown}</Markdown>;\n```\n\nAfter:\n\n```tsx\n<div class=\"markdown-body\">\n\t<Markdown>{markdown}</Markdown>\n</div>\n```\n\n### URL transforms\n\nBefore:\n\n```tsx\n<Markdown transformLinkUri={(href) => href} transformImageUri={(src) => src}>\n\t{markdown}\n</Markdown>;\n```\n\nAfter:\n\n```tsx\n<Markdown\n\turlTransform={(url, key) => {\n\t\tif (key === \"href\") return url;\n\t\tif (key === \"src\") return url;\n\t\treturn url;\n\t}}\n>\n\t{markdown}\n</Markdown>;\n```\n\n### Removed and deprecated behavior\n\n- `SolidMarkdown` is gone. Use the default export instead.\n- Wrapper props such as `class` and `className` are gone. Wrap `Markdown` in your own element.\n- Legacy pre-v9 props now throw at runtime instead of being silently accepted. This includes deprecated names such as `source`, `plugins`, `renderers`, `allowNode`, `allowedTypes`, `disallowedTypes`, `transformLinkUri`, `transformImageUri`, `linkTarget`, and the old source-position props.\n- `urlTransform` replaces `transformLinkUri` and `transformImageUri`.\n- `renderingStrategy=\"memo\" | \"reconcile\"` is a supported, Solid-specific prop on the synchronous `Markdown` export. This fork keeps it un-deprecated: `\"reconcile\"` is load-bearing for streaming DOM stability (it rebuilds the subtree each tick so growing content stays consistent), and consumers rely on it permanently.\n\n## Testing and status\n\nLocal verification for this port currently runs through:\n\n```bash\nbun run lint\nbun run typecheck\nbun run test\nbun run build\n```\n\nCurrent status:\n\n- Sync rendering is supported through `Markdown`.\n- Async unified plugins are supported on the server through `MarkdownAsync`.\n- Async unified plugins are supported on the client through `MarkdownResource`.\n- SSR and DOM behavior are covered by the package test suite.\n","readmeFilename":"README.md","_rev":"1-5753bc5cfd450dd427f96ed5d74ec37b"}