New line with react-markdown
Asked Answered
D

8

6

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>;
  }
}
Danitadaniyal answered 21/2, 2020 at 4:21 Comment(4)
You may want to replace \n\n to what you want using js feature directly.Torto
@Torto \n\n still works in input variable. So I dont think that is the problem.Danitadaniyal
I have the same issue. Markdown sourced from a .md file or hard-coded in a variable is rendered properly. I am also using Firestore, and any markdown pulled from there does not render properly. Carriage returns and headers are ignored. Do you find a solution?Breana
Does this answer your question? Firebase Firestore new line commandFurthermost
V
9

first create css class forexample

.foo {white-space: 'pre-wrap';}

then add classname to markdown component

<ReactMarkdown source={input} className="foo" />
Vidda answered 1/7, 2022 at 12:51 Comment(0)
G
4

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

Gromme answered 6/1, 2021 at 19:10 Comment(3)
This creates a new Paragraph, not a new line like <br/> tag does. What if you want to add a new line inside of a paragraph?Benally
Did you ever figure out how to get this behavior? @AntoniSilvestrovičCypro
@DeveloperRyan Honestly, I think I just ignored this problem at that time xD But right now I'd just use remark/rehype and add support for the <br/> tag, it would be the easiest approach.Benally
C
3

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

Cumbersome answered 4/2, 2023 at 5:35 Comment(0)
S
1

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");
}
Sulla answered 8/6, 2022 at 2:54 Comment(0)
A
1

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

Annis answered 24/8, 2023 at 20:11 Comment(0)
H
0

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"

Headpiece answered 30/5, 2023 at 15:19 Comment(0)
O
0

Add the following CSS to

tags 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

enter image description here

Organdy answered 27/6, 2024 at 18:31 Comment(0)
S
0

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.

Sexism answered 9/8, 2024 at 2:37 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.