Reputation: 61
I am trying to pull the markdown string from firebase database then using react-markdown to render it into Component. But the markdown string doesn't show correctly. I think the problem is due to start with new line.
I tried to declare the variable I put markdown in there. it works. markdown string which is created in Component
But the markdown string which is pulled from firebase database. it doesn't show correctly. markdown string which is pulled from firebase database
Here is my code
export default function BlogTemplate() {
const { id } = useParams();
useFirestoreConnect([
{
collection: "communications",
doc: id
}
]);
const post = useSelector(
state =>
state.firestore.data.communications &&
state.firestore.data.communications[id]
);
if (post) {
const input =
"# This is a header\n\nAnd this is a paragraph \n\n # This is header again"; // this is a markdown string created in Component
const postContent = post.content; // This is the markdown string pulled from firebase database
return (
<Layout>
<Container>
<Content className="pt-5 pb-5">
<ReactMarkdown source={input} />
<ReactMarkdown source={postContent} />
</Content>
</Container>
</Layout>
);
} else {
return <p>Loading...</p>;
}
}
Upvotes: 6
Views: 24365
Reputation: 20249
Adding the following CSS to <p> tag worked for me.
Add this to your CSS
.line-break {
white-space: pre-wrap;
line-height: 1.5;
}
Apply the css to <p>
tag only
<ReactMarkdown
className={`${customClass} mb-2`}
components={{
// add a css for p tags
p({ children }) {
return <p className='line-break'>{children}</p>;
},
code(props) {
....
}
}}
remarkPlugins={[remarkGfm]}
children={value}
/>
</div>
);
output
You can test it at https://pastelog.vercel.app
Upvotes: 1
Reputation: 8596
As @George pointed out use this quickfix to demonstrate that adding 2 whitespaces would fix the issue:
text = text?.replace(/\n/gi, " \n") ?? "";
As @Carneiro pointed out in the similar question and answer you can use the remark-breaks plugin.
Import like this:
import remarkBreaks from 'remark-breaks';
Use like this:
<ReactMarkdown remarkPlugins={[remarkBreaks]}>
{"line1\nline2"}
</ReactMarkdown>
I checked the plugin code and it basically just wraps mdast-util-newline-to-break with 112K weekly downloads.
Upvotes: 0
Reputation: 111
Solved: One way is to simply replace the new lines with HTML <br/>
should solve the problem.
Use ReactMarkdown with rehype-raw plugin.
text.replace(/\\n/gi, "\n").replace(/\n/gi, "<br/>");
e.g:
import rehypeRaw from "rehype-raw";
import remarkGfm from "remark-gfm";
const SomeComponent = () => {
const text = "Foo\nBar\nBaz";
return (
<ReactMarkdown
children={text}
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeRaw]}
/>
)
}
// Output
Foo
<br/>
Bar
<br/>
Baz
Upvotes: 1
Reputation: 299
Firestore stores the string as a plain test, some extra space, a new line and other characters are somehow removed by firestore.
I fixed this by saving my content encoded as base64 string
const encoded = Buffer.from(content).toString("base64") // on node nevironment
and then decode it back when I want to use it
const decoded = Buffer.from(encoded,"base64").toString("utf8") // on node environment
If you want to do encoding on browser, you will need to use other technics like "TextEncoder"
Upvotes: 0
Reputation: 31
If pre-wrap is applied to the entire markdown, the display will be weird in other parts, so I solved it like this.
import { styled } from '@mui/material/styles';
import { FC, ReactNode } from 'react';
import ReactMarkdown from 'react-markdown';
type Props = {
className?: string;
children?: ReactNode;
markdown: string;
};
const SC = {
P: styled('p')(({ theme }) => ({
whiteSpace: 'pre-wrap',
})),
};
const MarkDownView: FC<Props> = React.memo(function MarkdownView({ className, markdown }) {
return (
<ReactMarkdown
className={className}
remarkPlugins={[remarkGfm]}
components={{
p({ className, children, ...props }) {
return <SC.P className={className}>{children}</SC.P>;
},
}}
>
{markdown}
</ReactMarkdown>
);
});
export default MarkDownView;
Target is Paragraphs tag
Upvotes: 3
Reputation: 331
first create css class forexample
.foo {white-space: 'pre-wrap';}
then add classname to markdown component
<ReactMarkdown source={input} className="foo" />
Upvotes: 9
Reputation: 11
Hope help someone with this, when you retreive a string from firebase, I don't know why it adds an extra "/" to the new lines. Eg: "\n" => "\n". So you need to replace it like this:
const parseToMarkDown = (str: string): string => {
return str.replace(/\\n/g, "\n");
}
Upvotes: 1
Reputation: 59
It seems that you need to add 2 empty spaces before \n like this: "This is a header \n \nAnd this is a paragraph".
Let me know if that works for you.
More info here: https://github.com/remarkjs/react-markdown/issues/273
Upvotes: 4