--- myst: html_meta: "description": "" "property=og:description": "" "property=og:title": "" "keywords": "" --- # RichText Component Previously, we created pages for each content object and also established a structure with folders and internal linking. Now we need to display the data inside these pages the right way. In a Plone site, content objects may contain media such as images, videos and even files. The `plone.restapi` also returns text data in a content object such as a `PloneDocument` as stringified HTML which could contain media and internal linking. These cannot be directly used in a GatsbyJS site. Thankfully, the plugin is well equipped to handle these separately. Files and images are cached and backlinked to the page they are present in, with images even optimized with the [Sharp](https://github.com/lovell/sharp) plugin. The stringified HTML is processed and serialized. For usage with React, a `RichText` component deserializes this data and also handles media and internal linking. That was a lot of terminology and information, let us get into each part one by one so as to make things clear. ## Images And Files Media content such as Images and Files are processed separately by the plugin, stored in the cache and handled by the `gatsby-source-filesystem` plugin. ````{note} Some configuraton with `gatsby-source-filesystem` is required in the GatsbyJS site before it can query file nodes. Make sure it is installed and then update `gatsby-node.js` with: ```javascript { resolve: 'gatsby-source-filesystem', options: { path: `${__dirname}/src/static`, }, }, ``` And then create a `static` folder in the `src`. The plugin requires a folder to be used as source to work even when the file nodes are all generated by our source plugin. ```` Now files and images can be queried with GraphQL. In ```text allPloneFile(filter: { _backlinks: { eq: $path } }) { edges { node { id title file { filename publicURL } _path } } } allPloneImage(filter: { _backlinks: { eq: $path } }) { edges { node { id title image { publicURL childImageSharp { fixed(width: 600) { ...GatsbyImageSharpFixed } } } _path } } } ``` Files can be directly made downloadable by using the `publicURL` attribute. For images, we use a different approach altogether. They are first optimized and processed by Sharp plugins before they are used. Install them with `npm install gatsby-image gatsby-plugin-sharp gatsby-transformer-sharp` Add them to `gatsby-node.js`: ```javascript plugins: [ 'gatsby-plugin-sharp', 'gatsby-transformer-sharp' ], ``` Now, the images are available to be queried per the example above. ```{note} The fixed width used there is `600` but this can be changed according to your requirements. The whole range of options can be found in the [docs](https://www.gatsbyjs.com/plugins/gatsby-plugin-sharp/). ``` ## RichText Component We already know how images and files can be queried with GraphQL. To use them along with the HTML content, we use the RichText Component. Before we jump into that, let us inspect how HTML content is handled by the plugin. ### Exercise Explore GraphiQL at and compare the stringified HTML and serialized React version of the text data. Hints: Try checking the text field of the nodes of type `PloneDocument` ````{dropdown} Solution :animate: fade-in-slide-down :icon: question ```text { allPloneDocument { edges { node { id text { data react } } } } } ``` Notice that `node.text.react` is in serialized form that can be deserialized and used with React. ```` ```{note} Internally, [react-serialize](https://www.npmjs.com/package/react-serialize) is used by the RichText component to handle serialized HTML data. This eliminates the use of `dangerouslySetInnerHTML`, which is recommended to be avoided. ``` The following is a usage example of the RichText component. `Document.js` handles all nodes of type `PloneDocument` on page creation. ```jsx import RichText from './RichText'; const Document = ({ data, images = [], files = [] }) => (

{data.title}

{data.text ? ( ) : null}
); ``` Let us do a quick review of how it all falls in place together: - `default.js` is the template used for all content objects. - Internally in the template, based on the type, the appropriate component is selected. - Data is retrieved via GraphQL in the template itself based on the type. - For all types of content objects, images and files are queried separately with backlinks and passed in to the component. - In the components, RichText component is utilized to display HTML content with images, files and internal links.