https://codesandbox.io/s/quizzical-lake-16q4o?file=/pages/index.tsx
When replacing to a custom component, false will always be returned.
I am currently using the any type.
However, is there any other solution other than the any type?
Thanks for opening the issue @purp1eeeee
In your CodeSandbox example, you're not returning a React element so replace won't work. See readme.
So can you replace the logs with a return of your custom element?
export default function IndexPage() {
const html = "<h1>hoge</h1>";
const options: HTMLReactParserOptions = {
replace: (domNode) => {
- console.log(domNode);
- console.log(domNode instanceof Element);
+ if (domNode.name === "h1") {
+ return <h1>replaced</h1>;
+ }
}
};
return <div>{parse(html, options)}</div>;
}
See updated CodeSandbox.
I following this instruction, and I also have same problem, I can't get property attribs
from domNode
.
Because typescript check domNode
is instance of DOMNode
, not Element
type, so that the error occurs, because DOMNode
hasn't attribs
property.
And if you check with this condition console.log(domNode instanceof Element)
the return always false, because instance of domNode is DOMNode
.
I have solution for this, maybe can help. I defined the Element
type at the parameter domNode.
import parse, { HTMLReactParserOptions } from "html-react-parser";
import { Element } from "domhandler/lib/node";
export function contentHandler(postContent: string) {
const options: HTMLReactParserOptions = {
replace: (domNode: Element) => {
if (domNode.attribs) {
if (domNode.attribs.id === 'shortcode') {
return <div className="leadform">Shortcode</div>;
}
}
},
};
return parse(postContent, options);
}
I can confirm I'm having the same issue with a Next.js project; Typescript type-casting domNode
seems to be the only work around after upgrading html-react-parser.
@kakaeriel
so good! thank you👍
Having these issues with a Typescript project. Like @kakaeriel I'm following this instruction about replace including the section on Typescript.
The solution from @kakaeriel works for me. The instanceof
operator doesn't work (Element is not a type) and after hours browsing through node_modules looking for a type definition, finding this workaround is a life-saver.
Thanks for providing an alternative solution @kakaeriel. Would you be interested in creating a PR to improve the README.md
documentation?
@remarkablemark Yes sure! I will create a PR, ASAP.
Wow. I have the same issue using NextJS.
Because typescript check
domNode
is instance ofDOMNode
, notElement
type, so that the error occurs, becauseDOMNode
hasn'tattribs
property.```
So why does this only occur in a NextJS app.
I setup a react-scripts typescript app and there it works.
https://codesandbox.io/s/html-parsing-and-replacing-elements-yjtv7?file=/src/index.tsx
I'm not sure @Naxos84. I bet Next.js has a different TypeScript configuration. Please check out @kakaeriel's solution for a workaround.
@kakaeriel let me know if you're able to open a PR to update the README.md
with your workaround. If you're unable to do it, I can do it. Thanks!
I don't think that it is NextJs related.
I tried a little more and voila it worked somehow.
I changed @remarkablemark codesandbox and added console.log(domElement.constructor)
as mentioned on Stack Overflow.
The result looks as follows:
So I don't understand why it is suddenly working!?
Though it is not working in "my" nextjs project.
Update: And now it's not working again....
I suggest using a custom typeguard.
const isElement = (domNode: DOMNode): domNode is Element => {
const isTag = domNode.type === "tag";
const hasAttributes = (domNode as Element).attribs !== undefined;
return isTag && hasAttributes;
};
const parserOptions: HTMLReactParserOptions = {
replace: domNode => {
if (isElement(domNode)) {
return <p>It's an element.</p>;
} else {
return <p>It's something else</p>;
}
},
};
Hey everyone, I was able to fix this in Next.js 10.x with this solution. It's a public Gist where you can find my current implementation details. The solution has zero type errors in my setup.
@natterstefan Thanks for sharing your solution!
I have the same problem with NextJS. Element is always undefined. I typed domNode as any and converted the options type as HTMLReactParserOptions. Element from domhandler doesn't work with SSR?
const options = {
replace: (domNode: any) => {
// ...
}
} as HTMLReactParserOptions;
I was able to fix this with the code below, hope it would help
Most helpful comment
I following this instruction, and I also have same problem, I can't get property
attribs
fromdomNode
.Because typescript check
domNode
is instance ofDOMNode
, notElement
type, so that the error occurs, becauseDOMNode
hasn'tattribs
property.And if you check with this condition
console.log(domNode instanceof Element)
the return always false, because instance of domNode isDOMNode
.I have solution for this, maybe can help. I defined the
Element
type at the parameter domNode.