remarkjs / react-remark Goto Github PK
View Code? Open in Web Editor NEWReact component and hook to use remark to render markdown
Home Page: https://remarkjs.github.io/react-remark
License: MIT License
React component and hook to use remark to render markdown
Home Page: https://remarkjs.github.io/react-remark
License: MIT License
Using this library with the Snowpack build-tool produces the following error when trying to execute snowpack dev
:
[snowpack] ! installing dependencies...
[snowpack] Cannot find module '/workspace/example-project/node_modules/react-remark/dist/react-markdown.esm.js'
Require stack:
- /workspace/example-project/node_modules/esinstall/lib/index.js
- /workspace/example-project/node_modules/snowpack/lib/commands/install.js
- /workspace/example-project/node_modules/snowpack/lib/sources/local.js
- /workspace/example-project/node_modules/snowpack/lib/util.js
- /workspace/example-project/node_modules/snowpack/lib/commands/add-rm.js
- /workspace/example-project/node_modules/snowpack/lib/index.js
- /workspace/example-project/node_modules/snowpack/index.bin.js
I believe this is because the module
declaration in package.json
incorrect refers to a file named react-markdown.esm.js
instead of react-remark.esm.js
.
https://github.com/remarkjs/react-remark/blob/main/package.json#L14
Updating that property for my local installed version of the library seemed to have fixed the issue.
I'm trying to add some custom components for rendering certain elements.
I'm getting a Typescript error which I believe to be a typing error on the react-remark side, though maybe it's something I'm doing wrong.
lib/markdown.tsx:37:11 - error TS2322: Type 'FC<ArbitraryLinkProps>' is not assignable to type 'ComponentLike<ReactElement<{}, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'ComponentProps' has no properties in common with type 'PropsWithChildren<ArbitraryLinkProps>'.
Should I not be using React.FC in this case?
Not working with remark-prism.
Any lightweight syntax highlighter support.
Can't find any alternatives.
import React from "react";
import { Remark } from "@christianmurphy/react-remark";
const mycode = `
\`\`\`lol filename=bashrc
lets go
\`\`\`
`;
export default function Lol() {
return (
<Remark
remarkParseOptions={{ commonmark: true }}
remarkToRehypeOptions={{ commonmark: true }}
rehypeReactOptions={{
createElement: React.createElement,
components: {
code: (props) => {
console.log(props);
return <code {...props}>{props.children as string}</code>;
},
},
}}
>
{mycode}
</Remark>
);
}
I am curious how I should retrieve metadata from the code fence. Right now I am seeing {className: "language-lol", children: ["lets go↵"], ...(stuff that doesn't seem to contain what I want)}. Any advice?
Also in your examples the rehypeReactOptions do not have createElement: React.createElement. This field seems to be required, do the docs need updating or am I missing something?
latest
No response
Use rehypeReactOptions
I'm interested by create custom components like this:
components: {
"interactive-counter": Counter
}
Seems than custom components does not work, and give an empty
No response
No response
No response
No response
I have a couple of GFM tables in one of the documents I'm rendering. I'm getting a lot of output in the console like this:
Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <table>. Make sure you don't have any extra whitespace between tags on each line of your source code.
in table
in Remark (at markdown.tsx:33)
...
Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <thead>. Make sure you don't have any extra whitespace between tags on each line of your source code.
in thead
in table
in Remark (at markdown.tsx:33)
...
Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <tr>. Make sure you don't have any extra whitespace between tags on each line of your source code.
in tr
in thead
in table
in Remark (at markdown.tsx:33)
...
Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <tbody>. Make sure you don't have any extra whitespace between tags on each line of your source code.
in tbody
in table
in Remark (at markdown.tsx:33)
...
Warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <tr>. Make sure you don't have any extra whitespace between tags on each line of your source code.
in tr
in tbody
in table
in Remark (at markdown.tsx:33)
...
No response
I've tried to update @types/unist
to v3 from v2, but that causes a type error when trying to give Remark a list of plugins:
Type '() => (tree: Node) => Node' is not assignable to type 'Pluggable<any[], Settings>'.
Type '() => (tree: Node) => Node' is not assignable to type 'Plugin<any[], Settings>'.
Type '(tree: Node) => Node' is not assignable to type 'void | Transformer'.
Type '(tree: Node) => Node' is not assignable to type 'Transformer'.
Type 'Node' is not assignable to type 'void | Error | Node<Data> | Promise<Node<Data>> | Promise<void>'.
Type 'Node' is not assignable to type 'Node<Data>'.
Types of property 'data' are incompatible.
Type 'import("[...]/node_modules/.pnpm/@[email protected]/node_modules/@types/unist/index").Data | undefined' is not assignable to type 'import("[...]/node_modules/.pnpm/@[email protected]/node_modules/@types/unist/index").Data | undefined'.
Type 'import("[...]/node_modules/.pnpm/@[email protected]/node_modules/@types/unist/index").Data' is not assignable to type 'import("[...]/node_modules/.pnpm/@[email protected]/node_modules/@types/unist/index").Data'.
Index signature for type 'string' is missing in type 'Data'.
178 remarkPlugins={[remarkEntityLinks]}
~~~~~~~~~~~~~~~~~
This seems to be, because react-remark
is still using [email protected]
, which intern is still depending on @types/[email protected]
.
The types work with the most up to date versions of @types/unist
There is a type conflict in the Node
type between @types/unist@2
and @types/unist@3
No response
No response
No response
No response
2.1.0 && 4.0.0
https://codesandbox.io/p/devbox/2g4wrr?file=%2Fsrc%2FApp.tsx%3A30%2C3
Using react-remark and remark-gfm nothing renders
i tested with remark-gemoji and that seems to work fine, so could be that plugin or im missing a setup step
Should render
Tables should work
renders nothing
Node v17, Node v16
yarn 2, pnpm
Windows, macOS
Create React App, Vite
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates are currently rate-limited. Click on a checkbox below to force their creation now.
@testing-library/jest-dom
, @testing-library/react
, @testing-library/react-hooks
)These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
rehype-katex
, remark-gfm
, remark-math
, remark-parse
, remark-rehype
)@storybook/addon-essentials
, @storybook/react
)These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.
@types/react
, @types/react-dom
, react
, react-dom
, react-test-renderer
).github/workflows/gh-page.yml
actions/checkout v3
actions/setup-node v3
actions/cache v3
.github/workflows/main.yml
actions/checkout v3
actions/setup-node v3
actions/cache v3
package.json
rehype-react ^6.0.0
remark-parse ^9.0.0
remark-rehype ^8.0.0
unified ^9.0.0
@babel/core ^7.0.0
@storybook/addon-essentials ^6.0.0
@storybook/react ^6.0.0
@testing-library/jest-dom ^5.0.0
@testing-library/react ^12.0.0
@testing-library/react-hooks ^7.0.0
@types/react ^17.0.0
@types/react-dom ^17.0.0
husky ^7.0.0
katex ^0.13.0
pinst ^2.0.0
react ^17.0.0
react-dom ^17.0.0
react-test-renderer ^17.0.0
rehype-katex ^5.0.0
rehype-raw ^5.0.0
rehype-sanitize ^4.0.0
remark-gfm ^1.0.0
remark-math ^4.0.0
tsdx ^0.14.0
typescript ^3.0.0
react >=16.8
node >=10
I'm trying out react-remark and I'm struggling to get plugins working.
At the moment I'm just trying to follow the example. I've installed rehype-autolink-headings, imported it as in the example, and passed it in to the Remark component as in the example.
Headings are getting rendered exactly the same as when I don't add the plugin.
import rehypeAutoLinkHeadings from "rehype-autolink-headings";
...
return (
<Remark rehypePlugins={[rehypeAutoLinkHeadings]}>
{markdown}
</Remark>
);
Am I doing something wrong?
It appears that this repo is not actively being developed. I'm basing this on:
General lack of recent activity
#41 (comment) says:
remark plugins need to be remark 13 compatible. [..] The next major release will support remark 14
#39 hasn't received commits since Aug 25, 2021
Probably "archiving" this repo would be a bit much, likely work will pick up again at some point, but perhaps it would be helpful to at least add a notice near the top of the README.md
about the current limitations, namely the lack of support for remark
14.
remark
14.0.0 was released Aug 3, 2021. remark
13.0.0 was released Oct 14, 2020, and has not received any updates since then (the following release was 14.0.0).
Along the same lines, it would be great to add a "When should I use this?" section like rehype-react and react-markdown, to help steer people to the best option for their needs.
Willing to submit a PR if that would be helpful.
PS: Hope the above doesn't seem unkind in any way, remarkjs
contributors are doing and have done awesome work, which I very much appreciate. <3
How does this compare with react-markdown and remark-react in terms of architecture and performance?
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Location: package.json
Error type: The renovate configuration file contains some invalid settings
Message: Configuration option 'packageRules[0].node' should be a json object, Invalid configuration option: author, Invalid configuration option: bugs, Invalid configuration option: files, Invalid configuration option: funding, Invalid configuration option: license, Invalid configuration option: main, Invalid configuration option: module, Invalid configuration option: name, Invalid configuration option: packageRules[1].react, Invalid configuration option: packageRules[2].rehype-react, Invalid configuration option: packageRules[2].remark-parse, Invalid configuration option: packageRules[2].remark-rehype, Invalid configuration option: packageRules[2].unified, Invalid configuration option: packageRules[3].@babel/core, Invalid configuration option: packageRules[3].@storybook/addon-essentials, Invalid configuration option: packageRules[3].@storybook/react, Invalid configuration option: packageRules[3].@testing-library/jest-dom, Invalid configuration option: packageRules[3].@testing-library/react, Invalid configuration option: packageRules[3].@testing-library/react-hooks, Invalid configuration option: packageRules[3].@types/react, Invalid configuration option: packageRules[3].@types/react-dom, Invalid configuration option: packageRules[3].husky, Invalid configuration option: packageRules[3].katex, Invalid configuration option: packageRules[3].pinst, Invalid configuration option: packageRules[3].react, Invalid configuration option: packageRules[3].react-dom, Invalid configuration option: packageRules[3].react-test-renderer, Invalid configuration option: packageRules[3].rehype-katex, Invalid configuration option: packageRules[3].rehype-raw, Invalid configuration option: packageRules[3].rehype-sanitize, Invalid configuration option: packageRules[3].remark-gfm, Invalid configuration option: packageRules[3].remark-math, Invalid configuration option: packageRules[3].tsdx, Invalid configuration option: packageRules[3].typescript, Invalid configuration option: prettier, Invalid configuration option: renovate, Invalid configuration option: scripts, Invalid configuration option: sideEffects, Invalid configuration option: typings, Invalid configuration option: version, The "node" object can only be configured at the top level of a config but was found inside "packageRules[0]"
react-remark 2.1.0 and remark-gfm 3.0.1
https://stackblitz.com/edit/react-ts-zf4r6n?file=index.tsx
The linked code shows the problem. When I add a remark plugin (in this instance remark-gfm, but I also tried remark-math), there is no output and no errors.
I also tried this using the hook version and got null
as the rendered content.
If I dial back the version of remark-gfm to 1.0 as it is in this project's package.json
, then it works as expected.
I expected the markdown to be converted to HTML and the table in github flavored markdown to be correctly rendered.
Nothing is output at all, and there are no warning or error messages in the console.
No response
No response
No response
No response
Server rendering react-remark components by passing through an initial state value to useRemark, or using the component's children
.
Describe your issue here.
The useRemark hook's reactContent initial state is null. It looks like the only way to update this state is by using the exposed setMarkdownSource method.
The component sets the state of reactContent in a useEffect calling setMarkdownSource(children) which does not get executed on the server (by calling react-dom/server renderToString).
What are the alternative solutions? Please describe what else you have considered?
Have tried using the first example in README.md, which creates an infinite loop.
Looking through the source code, potential solutions:
setMarkdownSource uses unified.process which is async. We could create a synchronous function which uses unified.processSync to set the initial state based off a new prop in the useRemark hook e.g initialContent, though as I understand, if a provided remark plugin is async, this will throw an error.
I haven't tested this in a server rendered environment, however running this projects storybook seems to work ok with the following.
export const useRemark = ({
...,
initialContent,
}: UseRemarkOptions = {}): [ReactElement | null, (source: string) => void] => {
const initialParser = useCallback((source: string) => {
return unified()
.use(remarkParse, remarkParseOptions)
.use(remarkPlugins)
.use(remarkToRehype, remarkToRehypeOptions)
.use(rehypePlugins)
.use(rehypeReact, { createElement, Fragment, ...rehypeReactOptions })
.processSync(source).result as ReactElement;
}, []);
const [reactContent, setReactContent] = useState<ReactElement | null>(
() => initialContent ? initialParser(initialContent) : null
);
const setMarkdownSource = useCallback((source: string) => {
unified()
.use(remarkParse, remarkParseOptions)
.use(remarkPlugins)
.use(remarkToRehype, remarkToRehypeOptions)
.use(rehypePlugins)
.use(rehypeReact, { createElement, Fragment, ...rehypeReactOptions })
.process(source)
.then((vfile) => setReactContent(vfile.result as ReactElement))
.catch(onError);
}, []);
return [reactContent, setMarkdownSource];
};
export const Remark: FunctionComponent<RemarkProps> = ({
children,
...useRemarkOptions
}: RemarkProps) => {
const [reactContent, setMarkdownSource] = useRemark({
...useRemarkOptions,
initialContent: children,
});
useEffect(() => {
setMarkdownSource(children);
}, [children, setMarkdownSource]);
return reactContent;
};
For now, using react-markdown works fine (which seems to be synchronous) for our use case, however this project seems to align closer to our preference for parsing architecture).
Being able to server render initial content would be a useful feature.
2.1.0
https://codesandbox.io/s/wizardly-jepsen-1jeeyl
The plugins work without errors.
You get a bunch of weird errors about missing members.
remarkGfm gives the following error;
TS2322: Type '(options?: void | Options) => void | Transformer<Root, Root>' is not assignable to type 'Pluggable<any[], Settings>'. Type '(options?: void | Options) => void | Transformer<Root, Root>' is not assignable to type 'Plugin<any[], Settings>'. Type 'void | Transformer<Root, Root>' is not assignable to type 'void | Transformer'. Type 'Transformer<Root, Root>' is not assignable to type 'void | Transformer'. Type 'Transformer<Root, Root>' is not assignable to type 'Transformer'. Types of parameters 'file' and 'file' are incompatible. Type 'VFile' is missing the following properties from type 'VFile': value, stored, result, map
remarkBreaks gives;
TS2322: Type '() => void | Transformer<Root, Root>' is not assignable to type 'Pluggable<any[], Settings>'. Type '() => void | Transformer<Root, Root>' is not assignable to type 'Plugin<any[], Settings>'. Type 'void | Transformer<Root, Root>' is not assignable to type 'void | Transformer'.
remarkParse gives;
S2322: Type 'Plugin<[Options?] | void[], string, Root>' is not assignable to type 'Pluggable<any[], Settings>'. Type 'Plugin<[Options?] | void[], string, Root>' is not assignable to type 'Plugin<any[], Settings>'. The 'this' types of each signature are incompatible. Property 'attachers' is missing in type 'Processor<Settings>' but required in type 'Processor<Root, Root, void, void>'.
Node v16
npm 8
Windows
Webpack, Next.js
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.