Description
In Contentstack's JSON RTE I can create an ordered/unordered list. This list is then returned via GraphQL as follows:
{
uid: '123',
type: 'doc',
attrs: {},
children: [
{
uid: '456',
type: 'ul',
children: [
{
uid: '789',
type: 'li',
children: [
{
text: 'First thing',
},
],
attrs: {},
},
{
uid: '101112',
type: 'li',
children: [
{
text: 'Second thing',
},
],
attrs: {},
},
{
uid: '131415',
type: 'li',
children: [
{
text: 'Third thing',
},
],
attrs: {},
},
{
uid: '161718',
type: 'p',
attrs: {},
children: [
{
text: 'I am not a list item',
},
],
},
],
id: '192021',
attrs: {},
},
],
};
This will result in the following output:
<ul>
<li>First thing</li>
<li>Second thing</li>
<li>Third thing</li>
<p>I am not a list item</p>
</ul>
The above output does not adhere to the semantic HTML
The permitted content of <ul>
are the following tags: <li>
, <script>
and <template>
as described here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul
Since the data returned from Contentstack states that <p>I am not a list item</p>
is a child of <ul>
(it is in children
array), this results in incorrect HTML output as described earlier.
The only workaround is to check when rendering <ul>
children
whether the element is <li>
. If it isn't, it is wrapped with one. This may sound straightforward, but actually can be made significantly more complicated when rendering the component using a styling library (e.g. emotion or styled-components). Different APIs are exposed depending on the type of component, its nesting, styles applied, and whether it's rendered client or server side, making this a bit of a nightmare to work with.
The most reliable solution was to inject tagName="li"
prop for each <li>
. Then use this prop to check whether the component should be wrapped with <li>
or not.
The above workaround will then result in the following output:
<ul>
<li>First thing</li>
<li>Second thing</li>
<li>Third thing</li>
<li>
<p>I am not a list item</p>
</li>
</ul>
Although some may consider HTML output as not of high importance, when it comes to styling default list items via CSS, incorrect syntax will result in broken styles too.
Would be great to have this fixed at the data layer.