Skip to content

Commit

Permalink
Merge pull request #923 from storyblok/feature/PRO-613-add-new-richtext
Browse files Browse the repository at this point in the history
feat: add new richtext
  • Loading branch information
alvarosabu authored Nov 8, 2024
2 parents 3f56a14 + b6c257e commit 0e24b6d
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,95 @@ Which is the short-hand equivalent to using `useStoryblokApi` inside `useState`
## Rendering Rich Text

You can render rich text fields by using the `StoryblokRichText` component:

```html
<template>
<StoryblokRichText :doc="blok.articleContent" />
</template>
```

Or you can have more control by using the `useStoryblokRichText` composable:

```html
<script setup>
const { render } = useStoryblokRichText({
// options like resolvers
})
const root = () => render(blok.articleContent);
</script>

<template>
<root />
</template>
```

For more incredible options you can pass to the `useStoryblokRichText`, please consult the [Full options](https://github.com/storyblok/richtext?tab=readme-ov-file#options) documentation.


#### Overriding the default resolvers

You can override the default resolvers by passing a `resolver` prop to the `StoryblokRichText` component, for example, to use vue-router links or add a custom codeblok component: :

```html
<script setup>
import { NuxtLink } from '#components';
import type { StoryblokRichTextNode } from '@storyblok/vue';
import CodeBlok from "./components/CodeBlok.vue";
const resolvers = {
// NuxtLink example:
[MarkTypes.LINK]: (node: StoryblokRichTextNode<VNode>) =>
h(NuxtLink, {
to: node.attrs?.href,
target: node.attrs?.target,
}, node.text),
// Custom code block component example:
[BlockTypes.CODE_BLOCK]: (node: Node) => {
return h(CodeBlock, {
class: node?.attrs?.class,
}, node.children)
},
}
</script>
<template>
<StoryblokRichText :doc="blok.articleContent" :resolvers="resolvers" />
</template>
```
If you want to use the `useStoryblokRichText` composable, you can pass the `resolvers` via the options object:
```html
<script setup>
import CodeBlok from "./components/CodeBlok.vue";
const { render } = useStoryblokRichText({
resolvers: {
// NuxtLink example:
[MarkTypes.LINK]: (node: StoryblokRichTextNode<VNode>) =>
h(NuxtLink, {
to: node.attrs?.href,
target: node.attrs?.target,
}, node.text),
// Custom code block component example:
[BlockTypes.CODE_BLOCK]: (node: Node) =>
h(CodeBlock, {
class: node?.attrs?.class,
}, node.children)
}
});
const root = () => render(blok.articleContent);
</script>
```
### Legacy Rendering Rich Text
> [!WARNING]
> The legacy `richTextResolver` is soon to be deprecated. We recommend migrating to the new approach described above instead.
You can easily render rich text by using the `renderRichText` function that comes with `@storyblok/nuxt` and a Vue computed property:
```html
Expand Down
42 changes: 42 additions & 0 deletions playground/pages/richtext.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script setup lang="ts">
import { NuxtLink } from '#build/components';
import { MarkTypes, type StoryblokRichTextNode } from '@storyblok/vue';
const story = await useAsyncStoryblok(
"vue/test-richtext",
{
version: "draft"
}
// { resolveRelations: "Article.categories" }
);
const resolvers = {
[MarkTypes.LINK]: (node: StoryblokRichTextNode<VNode>) => {
return node.attrs?.linktype === "STORY"
? h(
NuxtLink,
{
to: node.attrs?.href,
target: node.attrs?.target
},
node.text
)
: h(
"a",
{
href: node.attrs?.href,
target: node.attrs?.target
},
node.text
);
}
};
</script>

<template>
<StoryblokRichText
v-if="story.content.richText"
:doc="story.content.richText"
:resolvers="resolvers"
/>
</template>
11 changes: 11 additions & 0 deletions playground/storyblok/iframe-embed/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
defineProps({
blok: {
type: Object,
required: true
}
});
</script>
<template>
<iframe :src="blok.url.url" class="w-full aspect-video" frameborder="0" />
</template>
6 changes: 6 additions & 0 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export default defineNuxtModule<ModuleOptions>({
'useStoryblokBridge',
'renderRichText',
'RichTextSchema',
'StoryblokRichText',
'useStoryblokRichText',
'MarkTypes',
'BlockTypes',
'LinkTypes',
'AssetTypes',
];
for (const name of names) {
addImports({ name, as: name, from: '@storyblok/vue' });
Expand Down

0 comments on commit 0e24b6d

Please sign in to comment.