SvelteKit Starter Kit
Words are nice... but code speaks louder. Dive into a fully commented project template, showcasing these techniques (and more) in action.
Sorry, no results found for "".
Rich text in DatoCMS is stored in Structured Text fields, which lets us use it in many different contexts, from HTML in the browser to speech fulfillments in voice interfaces, if that's what you want.
There's a lot to be said about Structured Text and the extensibility of it, but for now let's just say that it returns content in a particular JSON format called dast
which will resemble this example:
To make it easy to convert this format in HTML inside your Svelte projects, we released a package called @datocms/svelte
that exposes a <StructuredText />
component that does all the tedious work for you.
To take advantage of it, install the @datocms/svelte
package if you haven't already:
yarn add @datocms/svelte
Now let's make a GraphQL query to fetch a Structured Text field:
1const query = `2 query HomeQuery {3 blogPost {4 title5 content {6 value7 }8 }9 }10`;11
12export const load = () => {13 return executeQuery(query);14};
We can now feed the result to the data
prop of a <StructuredText />
component:
1<script>2import { StructuredText } from '@datocms/svelte';3
4export let data;5</script>6
7<article>8 <h1>{{ data.blogPost.title }}</h1>9 <StructuredText data={data.blogPost.content} />10</article>
Other than "regular" formatting nodes (paragraphs, lists, etc.), Structured Text documents can contain three special types of node:
itemLink
nodes are just like regular HTML hyperlinks, but point to other records instead of URLs;
inlineItem
nodes lets you directly embed a reference to a record in-between regular text;
block
nodes lets you embed a DatoCMS block record in-between regular paragraphs;
If a Structured Text document contains one of these nodes, then we need to change the GraphQL query, so that we also fetch all the records and blocks it references. As an example, if the field can link to other Blog posts, and can embed blocks of type "Image block", then the query should change like this:
1const query = `query HomeQuery {2 blogPostfirst {3 id4 title5 content {6 value7 blocks {8 ... on RecordInterface {9 id10 __typename11 }12 ... on ImageBlockRecord {13 image { url alt }14 }15 }16 links {17 ... on RecordInterface {18 id19 __typename20 }21 ... on BlogPostRecord {22 slug23 title24 }25 }26 }27 }28}`;
You must also tell <StructuredText />
how to render such nodes. By using the components
prop, you can declare an array of tuples composed of a predicate (a predicate is a function that takes one item as input and returns either true or false based on whether the item satisfies some condition) and a component: the predicate receives a node, and when it returns true, the custom component declared will be used to render the node:
1<script>2import { isBlock, isInlineItem, isItemLink } from 'datocms-structured-text-utils';3
4import { StructuredText } from '@datocms/svelte';5
6import Block from './Block.svelte';7import InlineItem from './InlineItem.svelte';8import ItemLink from './ItemLink.svelte';9</script>10
11<StructuredText12 data={blogPost.content}13 components={[14 [isInlineItem, InlineItem],15 [isItemLink, ItemLink],16 [isBlock, Block]17 ]}18/>