Displaying HTML Body on a page using ReactJS - html

Say I have the following code in my database (user input):
<html>
<title>Test</title>
<body>testing website</body>
</html>
And I fetched it correctly from my database using ReactJS. How can I display this in say: 'localhost:3000/play'? I don't want it to be rendered as raw data just like the code but I want it to actually render the html body as a website. (Title set to Test, and displays a small text: testing website). How can I do that in ReactJS? I already have /play configured and I just want to know how to display it there in the index.js file. I tried something like <div dangerouslySetInnerHTML={template} /> but it didn't work.

So, I fixed it with the following:
In a separate function:
db.getHTMLBody(key).then(snapshot => {
this.setState({ body: snapshot.val() })
})
then in the render:
<div dangerouslySetInnerHTML={{ __html: this.state.body }} />

Please try :
const innerHtml = { __html: escape(snapshot.val()) }
return(<div dangerouslySetInnerHTML={innerHtml} />)

Related

How to get inner html from an html page and display it on an angular component?

I have the following page "../posts/postxx.html", and I would like to programmatically take the innerHTML of the page (i.e. <h1>My Blog Post</>... etc.) and insert it in a div in an angular component? I've been trying like this on
ngOnIinit {
this.fileUrl = `../posts/${this.id}/${this.id}.component.html`;
fetch(this.fileUrl)
.then((r) => {
r.text().then((d) => {
let blog = d
console.log(blog);
})
})
},
}
but I'm getting cannot Get error: <pre>Cannot GET /posts/...!
Maybe just put an iframe in your html page :
<iframe [src]="fileUrl"></iframe>

Anchor Tag in Next.js

I'm tryin got use an anchor tag in Next.js
I don't get any console errors when I set it up and click the link, but the page does not jump to the id tag.
This issue on github suggests that people need to figure out a lot of custom code to use anchors. That can't be right.
I have:
const links = [
{ label: 'Solutions', href: '#solutions', id: 'solutions' },
]
<NavLink.Desktop key={index} href={link.href} id={link.id}>
{link.label}
</NavLink.Desktop>
I get no errors, but the page does not jump to the label that has an id of 'solutions'.
Does anyone know how to solve this, or where to go for ideas on how - it can't be intented that complex custom code is required to use an anchor tag?
Chakra UI has a Link component
<Link href='https://chakra-ui.com' isExternal>
Chakra Design system <ExternalLinkIcon mx='2px' />
</Link>
If you use the regular anchor tags
<Link href="#anchor_one">Menu one</Link>
<Link href="#anchor_two">Menu two</Link>
Then you can add the id for the anchors to the sections you want to navigate into
<div id="anchor_one" />
<div id="anchor_two" />
This can be either pages or components.
I hope this helped a little bit.
As said by #juliomalves in the comments, you have to specify the id attribute on the element in which you wish to navigate to. Not on the anchor tag.
The id for the anchor should be set on the element you want to link to, not on the link itself.
The below code works for me in Next.js -
export default function Home() {
return (
<div>
Click
<section
style={{ marginTop: "1000px", marginBottom: "1000px" }}
id="section"
>
<h1>Test</h1>
</section>
</div>
);
}
Your code should look like this -
const links = [{ label: 'Solutions', href: '#solutions', id: 'solutions' }]
<NavLink.Desktop
key={index}
href={link.href}
// id={link.id} - This is wrong, as you're referring to the same element
>
{link.label}
</NavLink.Desktop>
// Rather set the id attribute in a separate div/section element
<div id={link.id}>
<h2>Solutions</h2>
</div>
maybe try
const links = [
{ label: 'Solutions', href: '#solutions', id: 'solutions' },
]
<NavLink.Desktop key={index} href={links[0].href} id={links[0].id}>
{link.label}
</NavLink.Desktop>
since you only have 1 element in the links array, if you have multiple just map through the array
It is possible to scroll to anchor programatically using Router.push:
import { useRouter } from 'next/router'
const Foo = () => {
const { push } = useRouter()
const handleClick = () => {
push("#blah")
}
return (
<div>
<button onClick={handleClick}>Scroll</button>
<div>Foo</div>
<div>Bar</div>
<div id="blah">Blah</div>
</div>
)
}
Next.js recognises that you are passing something that is not a link to a new page and will concat it (in the example #blah) to the end of the URL.
Have a read about Link from next/link its a built in feature.
https://nextjs.org/docs/api-reference/next/link
https://github.com/vercel/next.js/blob/canary/examples/hello-world/pages/index.js#L7

How to do an image as a component template, with src as a property in Vue

I am trying to make a component for images in Vue. However, in my latest attempts, the only result is that an empty element is put in it's place.
In previous attempts, by putting a second element inside of the outer element, I was able to get it so that there was no image tag, and all of my props were displayed as a string:
<div> src=`${source}` alt=`${alternate}}` title=`${tit}}` width=`${w}}` height=`${h}}` /> </div>
My current code is:
<body>
<template id="comp-img-template">
<asimage source="uclx3S.jpg" alternate="red" tit="red" w="100" h="100"></asimage>
</template>
<script>.
Vue.component('asimage', {
props: ['source', 'alternate', 'tit', 'w', 'h'],
template: '<img src=`${source}` alt=`${alternate}}` title=`${tit}}` width=`${w}}` height=`${h}}` />'
})
new Vue({ el: '#comp-img-template' })
</script>
</body>
I am expecting there to be an image with the modifications present in the top portion, however as mentioned before I only get the empty tags
Your template string isn't valid HTML.
Something like this may work:
template: '< img :src="source" :alt="alternate" :title="tit" :width="w" :height="h" />'
Check out Vue v-bind syntax here: https://v2.vuejs.org/v2/guide/syntax.html#v-bind-Shorthand

React dangerouslySetInnerHTML not working when using variable

I'm creating an SPA using React that searches data and displays results. Each result follows the following model
{
"title": "A Title",
"body": " <li>escaped html&nbsp;<strong>that sould be rendered</strong>.</li>
</ul>"
}
The body property is always an escaped html that should be rendered in a component. This component looks like this:
Code
function SearchResult({ title, body, favourite }) {
return (
<article className="SearchResult">
<section>
<i className={`icon-star${favourite ? ' marked' : ''}`} />
{title}
</section>
<section
dangerouslySetInnerHTML={{ __html: body }}
className="SearchResult-body"
/>
</article>
);
}
but the body of each result is not being rendered correctly, instead, it shows the html as a text
The issue is that it only happens when I create the component passing a variable to the body property
results.map((result, index) => (
<SearchResult key={index} title={result.title} body={result.body} />
))
But if I do this, it works fine
<SearchResult
title="A title"
body=" <li>escaped html&nbsp;<strong>that sould be rendered</strong>.</li>
</ul>"
/>
Why is this different? Is there any preprocessing that I should add to the value before passing it in the property that is added by default when I use the fixed value?
Demo
A demo of this issue can be seen here
It seems like this issue only occurs when you give it an escaped html.
A solution implemented by #sergiotapia involves creating a helper function to unescape the html string to make it work.
htmlDecode(content) {
let e = document.createElement('div');
e.innerHTML = content;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
<section
dangerouslySetInnerHTML={{ __html: htmlDecode(body) }}
className="SearchResult-body"
/>
However as #brigand mentioned and I'll quote "Unescaping it could allow for XSS attacks and incorrect rendering." so this might not be the perfect solution for this.
See working example

reactjs dangerouslySetInnerHTML and dynamically adding classes to links

I'm new to reactjs and working on a project that is pushing json data to the template.
json structure
"description" : "Some text with a link and another link",
I propose using the following on the template
<p className='paragraph-margin-bottom-10 text--font-size-14 paragraph--justified' dangerouslySetInnerHTML={{ __html: lang.privacy[0].description }} />
but in terms of the output - I would maybe need to append a set of classes to ALL links. What is the best practice for this
so the links render with the following
<a class="text--font-size-14 hyperlink-primary" href="#">link</a>
I can imagine that many people will not agree with me. You can actually do this. But you shouldn't. It is bad enough that you want to use dangerouslySetInnerHTML. It is possible to parse html but there are many edge cases that you would need to handle.
Either tell your backend that they should return the links with proper classes or target the links inside the description directly with css.
See some similar question like: Using regular expressions to parse HTML: why not?
Using regular expressions to parse HTML: why not?
This is how I would do it. I will write the regex later if you run into some problems. I don't have much time to spare right now. Hope it will help. :)
import React from 'react';
import { render } from 'react-dom';
const htmlFromApi = 'some html from API'
const attachClassesToLinks = (htmlWithLinks) => {
// do something special
return htmlWithLinks
}
const App = () => (
<div>
<h1>My Component</h1>
<p dangerouslySetInnerHTML={{ __html: attachClassesToLinks(htmlFromApi) }} />
</div>
);
render(<App />, document.getElementById('root'));