Issue with serializer not applying styles to list items

15 replies
Last updated: Apr 14, 2020
Hello, I'm trying to add some styles to my list items, but my serializer is not working. Not sure why, any one spot the error? My serializer:

listItem: props => {
  switch (props.node.listItem) {
    case "bullet": {
      return <ul className="liststyle">{props.children}</ul>
    }
    case "number": {
      return <ol>{props.children}</ol>
    }
    default: {
      return <li>{props.children}</li>
    }
  }
},
Full serializer at
https://gist.github.com/AndreasJacobsen/de9a9eb192c8face517f9fd21313f974 , right now I'm trying to add the classname liststyle to a all ul elements in a block content component
Apr 14, 2020, 7:39 PM
Hi Andreas, does it work without the class? The code looks correct to me but you could try defining the components separately and replacing
<ul className="liststyle">{props.children}</ul>
with something like
<UlItem>{props.children}</UlItem>
. Perhaps it doesn’t like the quotation marks in the current approach, although that shouldn’t matter.
Apr 14, 2020, 8:03 PM
I'm getting "ULItem is not defined", so it seems to be ish working, but I cannot get the className, it's just an empty className
Apr 14, 2020, 8:08 PM
if I change it to say blockquote it stays as a ul without a css class, so the serializer is not hitting my bullet point list. Even thoug the graphQl tells me this is of type bullet
My sanity blockContent file has the following for lists

lists: [
        
{ title: 'Bullet', value: 'bullet' },
        
{ title: 'Numbered', value: 'numbered' },
      
],
Apr 14, 2020, 8:10 PM
The GraphQL output and
blockContent
content for lists look OK to me. Does it work if you remove all other serializers and just leave the
listItem
one?
Apr 14, 2020, 8:15 PM
does not work with only listItems either
Apr 14, 2020, 8:18 PM
Just to check a silly little thing: if you change
<ul className="liststyle">{props.children}</ul>
to
<p>{props.children}</p>
, are you seeing any change?
Apr 14, 2020, 8:19 PM
no, not seing any change at all
I'm calling it like this

<StatementBlock
  blocks={data.sanityAccessibilityStatement._rawStatement}
/>
with an import of course

import StatementBlock from "../components/Sanity/blockContent"

Apr 14, 2020, 8:21 PM
Hmm I’m having a hunch. I think you’re missing a list renderer. Here’s a basic example just to confirm it’s doing something:
const ListRenderer = ({ children }) => {
  return <ul>{children}</ul>;
};
const ListItemRenderer = ({ children }) => {
  return <li>{children}</li>;
};
const serializers = {
  ...,
  list: ListRenderer,
  listItem: ListItemRenderer,
  ...
}
Apr 14, 2020, 8:27 PM
Still the same error, I updated the gist with the code you so generously provided https://gist.github.com/AndreasJacobsen/de9a9eb192c8face517f9fd21313f974
Apr 14, 2020, 8:31 PM
but I also want to support numbered lists (edit, I can just make a switch case inside the listRender I realized)
Edit2: I updated the gist to contain more files, I just don't understand why this is not working. feel free to reply tomorrow instead though!
Apr 14, 2020, 8:32 PM
Just tested the above code locally and can confirm it’s working, also with a class name on the
ul
element. Are the other serializers working for you?
Apr 14, 2020, 8:38 PM
no, I updated the gist to also include the file where I'm using the blockContent compontent, I can add/remove classnames the titles and the other elements defined over listItem
Apr 14, 2020, 8:39 PM
Nasty 🤓 It doesn’t give any errors because the missing bracket is added at the end, but it’s enough to make it all fail. There’s one closing bracket missing to close off
types
and there’s one extra bracket at the very end of
serializers
if you do close off
types
before.
Try this:

const serializers = {
  types: {
    block(props) {
      switch (props.node.style) {
        case "h1":
          return <h1 className="title is-1 introTitle">{props.children}</h1>
        case "h2":
          return <h2 className="title is-2 introTitle">{props.children}</h2>
        case "h3":
          return <h3 className="title is-3 introTitle">{props.children}</h3>
        case "h4":
          return <h4 className="title is-4 introTitle">{props.children}</h4>
        case "blockquote":
          return <blockquote>{props.children}</blockquote>
        default:
          return <p>{props.children}</p>
      }
    }
  },
  list: ListRenderer,
  listItem: ListItemRenderer,
  figure(props) {
    return <Figure image={props.node} />
  },
  marks: {
    internalLink: ({ mark, children }) => {
      const { slug = {} } = mark
      const href = `/${slug.current}`
      return <Link to={href}>{children}</Link>
    },
    externalLink: ({ mark, children }) => {
      const { blank, href } = mark
      return blank ? (
        <a href={href} target="_blank" rel="noopener noreferrer">
          {children}
        </a>
      ) : (
        <a href={href}>{children}</a>
      )
    }
  }
}
Apr 14, 2020, 8:55 PM
It works :party_parrot: :party_parrot: :party_parrot: :party_parrot:Thank you Peter, you are amazing
Apr 14, 2020, 8:56 PM
I may have over estimated my switch case abilities, do you know how I can write a switch case for the list items?

const ListRenderer = ({ children }) => {
  
switch (children.props.node.listItem) {
    
case "bullet":
      
return <ul _className_="liststyle">{children}</ul>
    
default:
      
return (
        
<ol>
          
{children}
         
</ol>
      
)
  
}

}
WIth this all items are returned as &lt;ol&gt; lists (default), even the ones that are supposed to be unordered lists
Edit: using children.props.node.listItem I get an error stating "Cannot read property 'node' of underfined
Apr 14, 2020, 9:30 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?