How to create a custom data structure for quotes in Portable Text
9 replies
Last updated: Aug 22, 2021
I’ll answer this in this thread
user G
https://sanity-io-land.slack.com/archives/C9Z7RC3V1/p1629622858355200?thread_ts=1629622097.354200&cid=C9Z7RC3V1 Aug 22, 2021, 9:05 AM
What you describe here is essentially a data structure that consists of a quote (a text string) and an author name (a text string). Portable Text lets you insert custom data structures in between paragraphs (which also are their own objects really. The way I’d do this would be to first define a new object type:
Remember to import this into your schemas in
// quote.js export default { name: 'quote', type: 'object', title: 'Quote', fields: [ { name: 'text', type: 'text', // <= This can also be a Portable Text field title: '', }, { name: 'author', type: 'string', // <= This could be a reference to an author document type, if you had that title: 'Author', } ] }
schema.jsand then you can add the following to your Portable Text field (I’ve made a simple one here:
// portableText.js export default { name: 'portableText', type: 'array', title: 'Portable Text', of: [ { type: 'block', }, { type: 'quote', } ] }
Aug 22, 2021, 9:13 AM
Come think of it, you could also add support for an URL in the quote (reasoning in a bit):
// quote.js export default { name: 'quote', type: 'object', title: 'Quote', fields: [ { name: 'text', type: 'text', // <= This can also be a Portable Text field title: '', }, { name: 'author', type: 'string', // <= This could be a reference to an author document type, if you had that title: 'Author', }, { name: 'url', type: 'url', title: 'URL', description: 'Source on the web', } ] }
Aug 22, 2021, 9:16 AM
D
Amazing! This was really helpful and I’ve already got it set up in my codebase now. Very quick and easy to implement 😀👍
Aug 22, 2021, 9:17 AM
And the serializer for this in the frontend can be something like this:
Just went on a
🐰 🕳️ on how to properly markup this with HTML5. Not super obvious tbh. This seems like a reasonable solve .
// portableText.js const serializers = { type: { quote: ({ text, author, url }) => { return ( <figure> <blockquote cite={url}> {text} </blockquote> {author && <figcaption>{author}</figcaption>} </figure> ) } } }
🐰 🕳️ on how to properly markup this with HTML5. Not super obvious tbh. This seems like a reasonable solve .
Aug 22, 2021, 9:25 AM
D
Any idea why the above code wouldn’t work?
I’m getting the data through in my block content as I can see the quote in GrapQL.
When I add the word ‘test’ in after the {text} variable, in the serializer, that’s showing up i.e.:
But the actual text and author is not showing up.
The serializers are in a separate js file and are piped into my block content like:
I’m getting the data through in my block content as I can see the quote in GrapQL.
When I add the word ‘test’ in after the {text} variable, in the serializer, that’s showing up i.e.:
<blockquote>{text} test</blockquote>
The serializers are in a separate js file and are piped into my block content like:
<BlockContent serializers={serializers} />
Aug 22, 2021, 9:39 AM
oh, I forgot the pattern should be
That is including
// portableText.js const serializers = { type: { quote: ({node: { text, author, url }}) => { return ( <figure> <blockquote cite={url}> {text} </blockquote> {author && <figcaption>{author}</figcaption>} </figure> ) } } }
nodein
({node: { text, author, url }})
Aug 22, 2021, 9:44 AM
Wrote this up here btw https://sanity-io-land.slack.com/archives/C9YQ161LZ/p1629625376190900
Aug 22, 2021, 9:45 AM
D
Lovely, that’s working now. Thanks again, this was really helpful 👍
Aug 22, 2021, 9:46 AM
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.