Audience
If you encounter an error like this while trying to render a markdown with react-markdown and you're using parcel
Uncaught TypeError: Cannot convert undefined or null to objectCannot read properties of undefined (reading 'src')
this article is for you 🙂
This error should be fixed in parcel 3.x, that hasn't been released yet when I wrote this article.
TL;DR
yarn add react-markdown information-property
// my react-markdown wrapper componentimport 'property-information';
// package.json{"@parcel/resolver-default": {"packageExports": true}}
Introduction
I love Parcel. It's very easy to use without bloated configuration (see webpack) and it's fast. Yeah, sometimes I get errors while adding dependencies and I have to clean everything up (is it only me), but apart of that I really appreciate it.
A few days ago I needed to render markdown on my page, so I opted for react-markdown
.
The first thing I did was to add react-markdown
to my package.json:
yarn add react-markdown
and I also added remark-gfm
to support autolink literals, footnotes, strikethrough, tables, tasklists in markdown:
yarn add remark-gfm
then I created my MdPage component
import * as React from 'react';import ReactMarkdown from 'react-markdown';import remarkGfm from 'remark-gfm';interface Props {githubUrl: string;url: string;}const MdPage = ({ url, githubUrl }: Props) => {const { setAppError } = useAppContext();const [md, setMd] = React.useState('');React.useEffect(() => {fetch(url).then((res) => res.text()).then(setMd).catch((err) => {console.error('Failed to load page', err);setAppError('Failed to load page');});}, [url]);return (<Wrapper><Container.Container><Container.FlexRow className="items-end justify-end w-full"><Container.Container><Link.Button href={githubUrl} target="_blank"><Icon.FaGithub className="inline mr-2" size={24} /> View on GitHub</Link.Button></Container.Container></Container.FlexRow><Container.Container className={'markdown'}>{md && (<ReactMarkdownremarkPlugins={[remarkGfm]}>{md}</ReactMarkdown>)}</Container.Container></Container.Container></Wrapper>);};
But no matter what I got this error as soon as I started to render my markdown page:
Cannot read properties of undefined (reading 'src')
The first thing I thought was that my markdown was the issue, which sounded weird considering that I always folllow all the guidelines with markdown, but I thought that maybe the images which had a relative path to the repo could lead to this issue.
I tried with the markdown of the example of react-markdown
and I still got that issue.
Finally I just rendered this
const markdown = `A paragraph with *emphasis* and **strong importance**.`;
And finally it worked.
So, apparently as soon as I place a img
or a link in my markdown the engine dies.
I will avoid the step-by-step journey in trying several plugins and other things in the react-markdown configuration to see if using a custom component could work or if I was missing a certain plugin. It just didn't work.
All my attempts failed, until I found this issue on Github.
So here the OP says he's using parcel and whenever he tries to use a link he gets Cannot convert undefined or null to object
. Looks familiar uh?
So apparently they say that parcel has issues with react-markdown for whatever reasons, BUT, the fix shown in the issue actually SOLVES the issue.
Let's see how to implement it.
Fix
Information property
So apparently all we have to do is to install information-property
and to import it. But wait, what is information-property?
From the README
What is this? This package contains lots of info on all the properties and attributes found on the web platform. It includes data on HTML, SVG, ARIA, XML, XMLNS, and XLink. The names of the properties follow hast’s sensible naming scheme. It includes info on what data types attributes hold, such as whether they’re booleans or contain lists of space separated numbers.
When should I use this? You can use this package if you’re working with hast, which is an AST for HTML, or have goals related to ASTs, such as figuring out which properties or attributes are valid, or what data types they hold.
Ok, whatever, I actually have no idea of what this does, but it works, so let's implement the fix:
In our MdPage component just add
import 'property-information';
And eventually also add this to your package.json
"@parcel/resolver-default": {"packageExports": true}
And this should definetely fix the issue with react-markdown on parcel.
Extra: tailwindcss styles
Ok, this is actually not related with the issue described, but in case you use tailwindcss don't forget to remove the tailwindcss styles from the markdown.
Just add a markdown
class to ReactMarkdown
and add this rule to your css:
.markdown > * {all: revert;overflow-x: hidden;}