-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error when using html-react-parser #2517
Comments
The issue it that the package itself expects to have a Instead of trying to run the html parser in SSR, run it on client side. I tried this package locally. import * as parser from 'html-react-parser';
const parse = parser.default;
export default function Homepage() {
const data = useLoaderData<typeof loader>();
const [parsedHtml, setParsedHtml] = useState<ReturnType<typeof parse>>();
useEffect(() => {
setParsedHtml(parse('<p>bar</p>'));
});
return (
<div className="home">
{parsedHtml && <div>{parsedHtml}</div>}
</div>
);
} Make sure to add the parser package in the
|
Thanks @wizardlyhel Moving this to client-side would be problematic because in our case we receive markup or markdown from a CMS response. This would require making the entire page client-side, as individual pieces of the structured data received from the CMS may o may not have HTML. Additionally, this works on Hydrogen Remix classic (no Vite), and it also works on Vite + Remix (no Hydrogen/Oxygen). We're currently unable to migrate to Vite + Hydrogen because this is blocking the implementation. |
Then I would consider using dompurify + jsdom.
I don't know what other limitations these 2 package can run into when executed on the server side. They could be:
The core of any html sanitizer is that they relies on there is a DOM object that they can parse strings into html nodes and run queries to manipulate the node elements. Instead of writing a DOM object, they just reuse the ones from browser. But often, package like jsdom provides way more than just a simple parse and query dom nodes since these packages are used for unit testing. So these dom packages are really large in size because they try to mimic everything, including downloading scripts, that a browser dom does. |
I tried using dompurify as well and it had a similar error, I will try it with jsdom. That said, I still do not understand why this works as expected on all other SSR frameworks out there, this seems to be a problem specific to Oxygen/Hydrogen. As I mentioned, we currently have sites deployed to production running on Hydrogen + Remix classic and there's no errors. The server should not be trying to parse these into HTML, I tried using this other plugin https://www.npmjs.com/package/isomorphic-dompurify to no avail. And as described in kkomelin/isomorphic-dompurify#214 (comment) it looks like Hydrogen is loading the wrong file? |
It depends on the hosting environment you are on. Some hosting platform supply a global.windows object and some don't. For example, Vercel and Cloudflare workers (what Oxygen is using) doesn't have a global.windows object. The reason why windows often isn't defined is due to performance. To be honest, the fact that I have to do this kinda import workaround when using
This already tells me that the library export is set up oddly. Most likely the difference between es modules setup and cjs setup (what html-react-parser most likely is using). Since you are saying that this package "should" work on SSR, the file is there and it's just using the wrong one. Why not look into the option of patching the package so that it returns the correct file? https://www.npmjs.com/package/patch-package |
Another option is just copy the entire package content locally into your project and see if that works |
That's odd, I'm not sure why on your environment you have to import the package that way, for us to works as a normal import. For example, a simplified hook that parses HTML: import parse from 'html-react-parser';
export const useHTMLParser = (html) => {
return typeof html === 'string' ? parse(html) : html;
}; The production environments we have are hosted in Oxygen/Cloudflare and the parser works as expected. |
You have to ensure that the import {createRequire} from 'node:module';
const require = createRequire(import.meta.url);
// This needs to be resolved to the server-side version of html-dom-parser
// since running this on the edge will throw an error.
const htmlDomParserPath = require.resolve(
'html-dom-parser/lib/server/html-to-dom',
);
export default defineConfig({
resolve: {
alias: [
{
find: 'html-dom-parser',
replacement: htmlDomParserPath,
},
],
},
ssr: {
optimizeDeps: {
include: ['html-react-parser'],
},
},
}) |
@dcodrin wow, you're a savior! This is exactly what I was missing. Thank you so much! |
What is the location of your example repository?
No response
Which package or tool is having this issue?
Hydrogen
What version of that package or tool are you using?
2024.7.4
What version of Remix are you using?
2.10.1
Steps to Reproduce
html-react-parser
as a dependencyExpected Behavior
Server should not try to execute DOM methods, the
html-react-parser
package supports SSR.Actual Behavior
The server crashes with the error:
Error: This browser does not support document.implementation.createHTMLDocument
.The text was updated successfully, but these errors were encountered: