Closed petertenhoor closed 5 years ago
@petertenhoor - hmm... this code works by asking the browser, itself, what elements it recognizes. It sounds like you want the even more restrictive componentsOnly
.
<JsxParser
components={{ ComponentA, ComponentB }}
componentsOnly
jsx={`
<ComponentA>Text!</ComponentA>
<div>Omitted</div>
<ComponentB>More Text!</ComponentB>
`}
/>
This should omit the div
entirely, but never run that check above, because allowUnknownElements
is still true
. These lines are the current test which validates this functionality working. As you can see, it omits the h1
and h2
normal tags entirely, but still renders the div
tags that are defined by the stated valid elements. The check in the code happens before the allowUnknownElements
check as well, and will prevent the problematic line from being hit at all if enabled.
If that doesn't work for you, let me know and we can certainly work to fix it.
Thank you for your response.
My JSX string has both HTML and react components in it, so componentsOnly results in the parser not rendering my html:
err while rendering jsx parser Error: The componenet <p> is unrecognized, and will not be rendered.
My API for example returns the following JSX / HTML string:
"\n<HeadlessRow marginBottom={80}>\n \n<HeadlessColumn width={100}>\n \n<HeadlessText colorTheme=\"dark\" fontType=\"light\">\n <p>Zipcode finder</p>\n</HeadlessText>\n\n</HeadlessColumn>\n\n</HeadlessRow>\n<HeadlessRow rowStretch=\"stretch_row\" contentAlignment=\"middle\" backgroundColor=\"red\">\n \n<HeadlessColumn width={50} marginBottom={40}>\n \n<ImageShortcode image=\"https://ribsdelivery.test/wp-content/uploads/2019/08/burger.png\" imageFull=\"https://ribsdelivery.test/wp-content/uploads/2019/08/burger.png\" maxWidth=\"100%\" align=\"left\" linkTarget=\"_self\" decorationType=\"waves\" decorationColor=\"yellow\" decorationPosition=\"top-left\">\n</ImageShortcode>\n</HeadlessColumn>\n\n<HeadlessColumn width={50} marginTop={80} marginBottom={80}>\n \n<HeadlessText colorTheme=\"light\" fontType=\"bold\">\n <h2>Je eigen<br />\nRibs Delivery</h2>\n<p>In onze bezorgrestaurants worden onze vleesgerechten vers klaargemaakt. Geen fastfood, maar gerechten van hoge kwaliteit en met zorg bereid.</p>\n</HeadlessText>\n<Button text=\"Meer weten\" linkUrl=\"http://127.0.0.1:1337/franchise\" color=\"yellow-primary\" align=\"left\">\n</Button>\n\n</HeadlessColumn>\n\n</HeadlessRow>\n<HeadlessRow rowStretch=\"stretch_row\" contentAlignment=\"middle\" marginBottom={80} backgroundColor=\"yellow\">\n \n<HeadlessColumn width={50} marginTop={80} marginBottom={80}>\n \n<HeadlessText colorTheme=\"light\" fontType=\"bold\">\n <h2>Bezorger<br />\nworden?</h2>\n<p>In onze bezorgrestaurants worden onze vleesgerechten vers klaargemaakt. Geen fastfood, maar gerechten van hoge kwaliteit en met zorg bereid.</p>\n</HeadlessText>\n<Button text=\"Bekijk vacatures\" linkUrl=\"http://127.0.0.1:1337/over-ribs-delivery\" color=\"red-primary\" align=\"left\">\n</Button>\n\n</HeadlessColumn>\n\n<HeadlessColumn width={50} marginTop={40}>\n \n<ImageShortcode image=\"https://ribsdelivery.test/wp-content/uploads/2019/08/bezorger.png\" imageFull=\"https://ribsdelivery.test/wp-content/uploads/2019/08/bezorger.png\" maxWidth=\"100%\" align=\"right\" linkTarget=\"_self\" decorationType=\"zigzag\" decorationColor=\"red\" decorationPosition=\"bottom-right\">\n</ImageShortcode>\n</HeadlessColumn>\n\n</HeadlessRow>\n<HeadlessRow marginTop={80}>\n \n<HeadlessColumn width={100}>\n \n<HeadlessText colorTheme=\"dark\" fontType=\"light\">\n <h1>Ribsdelivery<br />\nDelicious to the bone</h1>\n</HeadlessText>\n\n</HeadlessColumn>\n\n</HeadlessRow>\n<HeadlessRow marginBottom={80}>\n \n<HeadlessColumn width={50}>\n \n<HeadlessText colorTheme=\"dark\" fontType=\"light\">\n <p>Ribsfactory Tilburg is gevestigd in het verlengde deel van de Heuvel, de hoofdwinkelstraat in het centrum van Tilburg. Dit laatste deel van de Heuvel wordt in de volksmond ook wel ‘korte’ Heuvel genoemd en maakt met zijn gezellige horecagelegenheden deel uit van het bruisende uitgaansleven van Tilburg. Vlakbij vindt je het befaamde poppodium 013 en ook de Pathé bioscoop ligt op looppafstand. In het winkelgebied van Tilburg is het elke week koopzondag. Je kunt een bezoek aan Ribsfactory dan ook uitstekend combineren met een dagje winkelen. Maar een heerlijk spareribsmenu is uiteraard ook een prima start van je avondje uit!</p>\n</HeadlessText>\n\n</HeadlessColumn>\n\n<HeadlessColumn width={50}>\n \n<HeadlessText colorTheme=\"dark\" fontType=\"light\">\n <p>Ribsfactory Tilburg is gevestigd in het verlengde deel van de Heuvel, de hoofdwinkelstraat in het centrum van Tilburg. Dit laatste deel van de Heuvel wordt in de volksmond ook wel ‘korte’ Heuvel genoemd en maakt met zijn gezellige horecagelegenheden deel uit van het bruisende uitgaansleven van Tilburg. Vlakbij vindt je het befaamde poppodium 013 en ook de Pathé bioscoop ligt op looppafstand. In het winkelgebied van Tilburg is het elke week koopzondag. Je kunt een bezoek aan Ribsfactory dan ook uitstekend combineren met een dagje winkelen. Maar een heerlijk spareribsmenu is uiteraard ook een prima start van je avondje uit!</p>\n</HeadlessText>\n\n</HeadlessColumn>\n\n</HeadlessRow>"
This is my React component calling react-jsx-parser:
import PropTypes from "prop-types";
import JsxParser from "react-jsx-parser";
import {shortcodeComponents} from "../../utils/shortcodeLibrary";
const ShortcodeContent = ({content}) => {
return (
<JsxParser renderInWrapper={false}
onError={(err) => console.log('err while rendering jsx parser', err)}
allowUnknownElements={true} //FIXME this should be false, but breaks SSR
componentsOnly={false}
components={shortcodeComponents}
jsx={content}/>
)
}
ShortcodeContent.defaultProps = {
content: ""
}
ShortcodeContent.propTypes = {
content: PropTypes.string
}
export default ShortcodeContent;
This is my shortcodeLibrary.js which is the object I pass to react-jsx-parser as Components prop:
import dynamic from "next/dynamic";
const HeadlessRow = dynamic(() => import("../components/ShortcodeContent/HeadlessRow"))
const HeadlessColumn = dynamic(() => import("../components/ShortcodeContent/HeadlessColumn"))
const HeadlessText = dynamic(() => import("../components/ShortcodeContent/HeadlessText"))
const HeadlessLink = dynamic(() => import("../components/ShortcodeContent/HeadlessLink"))
const Button = dynamic(() => import("../components/ShortcodeContent/Button"))
const ImageShortcode = dynamic(() => import("../components/ShortcodeContent/Image"))
const GravityForm = dynamic(() => import("../components/ShortcodeContent/GravityForm"))
const shortcodeComponents = {
HeadlessRow,
HeadlessColumn,
HeadlessText,
HeadlessLink,
Button,
ImageShortcode,
GravityForm,
}
export {shortcodeComponents}
I just wanted to make sure that if the API would give me an unknown React string, that it would not be rendered as a not existing HTML element. But as soon as I set allowUnknownElements to true, it gives me the document is not defined error. Which means it's not compatible with SSR.
Hi there,
We use JsxParser in a Next.js application to render some React Components and HTML from a string and it does exactly that which is great. There is just one issue we ran in to today:
I'd like to set the allowUnknownElements prop to true to ensure React components which are not in my component library will not be rendered.
When I put the allowUnknownElements to true, our server side rendering throws an error in react-jsx-parser/source/components/JsxParser.js:162:36:
It is triggered by this if statement which references the document:
Rendering the JsxParser only in the client is not an option for us, because the components have SEO value and should be in the source code.
Would it be possible to use a SSR friendly way to check if an element is in the given component array?