Sometimes you will get a string that you can't control in your React components (like from a CMS or API). It might look something like this:
"Wow I am so cool \n I'm a JavaScript haiku \n render my newlines"
But, those little \n
characters aren't respected if you were to put it into a React (or Vue) component, like this:
const haiku = "Wow I am so cool \n I'm a JavaScript haiku \n render my newlines"
function BeautifulHaiku() {
return <div>{haiku}</div>
}
If you want to change this behavior and get the newlines you want, you have a couple solid options.
Replace \n
with <br />
The first thing you can do is split up the string and then render the resulting <br />
tags.
function replaceWithBr() {
return haiku.replace(/\n/g, "<br />")
}
In React, you'd then use dangerouslySetInnerHTML
to make that work:
<p dangerouslySetInnerHTML={{__html: replaceWithBr()}} />
(this is named "dangerous" for a reason, and it's not because the React team wants to seem cool, it's because you gotta be careful about what you put in there to avoid malicious scripts)
And in Vue, you'd use v-html
to make that work:
<p v-html="replaceWithBr()">{{haiku}}</p>
Use CSS white-space
The other way you can do this is by using the white-space
CSS property and set it to either pre-wrap
or pre-line
.
.css-fix {
white-space: pre-wrap; /* or pre-line */
}
These two make sure that the text wraps when line breaks are in the content, and pre-line
specifically collapses multiple whitespaces into one.
This can be applied to both React and Vue!
Prove it, Cassidy
Fine, twist my arm!
Here's the React examples in action:
And here's the Vue examples!
"They're different but they're friends" - DJ Khaled
Full disclosure: I am not a Vue developer, this just happened to work for me when I tried it. I know this is "proper" in React but I can't speak for Vue because I am a noob. Good luck, have fun, make good choices, be kind, write code.
I hope this was helpful for you!
Top comments (11)
It was a great read, thanks.
A bit of addition: In Vue, one can also do. Codesandbox: codesandbox.io/s/demo-v-html-97ow8e
Ahhh I was wondering if that was a thing but didn't bother trying, thanks for sharing!
True. Don't forget to sanitize it if it can come from a user input (to avoid malicious code).
Thanks Cassidy! I have an issue to work on that I basically need to do this (swap out one tag for another), but my team wants me to try to avoid using ‘dangerouslySetInnerHTML’. This gives me the idea to see if css can do anything for me, but I worry it might not because it’s not a white space issue (I’m actually trying to swap tags with a specific component we have for highlighting text.) I’ll play around with it some more!
That's great! Thanks for sharing it with us
Thanks, .css-fix with white-space attribute works with Vue3, thanks (after I have spent the whole afternoon trying to find a solution). v-HTML is not recommended because of the malicious code injection possibility.
react-dom.development.js:12056 Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
You're not passing the
body
variable to your function!Thanks Cassidy! I appreciate it
Or you make an array by splitting the strings and then insert the br tags wherever you need.
I'd do it with flatMap:
https://codesandbox.io/s/young-bash-4vevii?from-embed=&file=/src/App.js
That's great! Thanks. ❤