Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nuxt components inside Storyblok Rich-Text editor #22

Closed
cetchells opened this issue Sep 29, 2022 · 4 comments
Closed

Nuxt components inside Storyblok Rich-Text editor #22

cetchells opened this issue Sep 29, 2022 · 4 comments

Comments

@cetchells
Copy link

I saw your post here: nuxt static, really helpful.
I had a look at nuxt3 and storyblok just wondering if you got components in richtext editor to resolve in nuxt3.
Suggestions below don't seem to work
https://www.storyblok.com/tp/nuxt-components-inside-rich-text

@SebbeJohansson
Copy link
Owner

Hi @cetchells. Am i understanding it correctly that you are wondering about adding blocks using this feature?
image
image

I have not tested that. I can take a look during next week if you want?

@cetchells
Copy link
Author

Yeh exactly that.
There is a related issue in storyblok/nuxt repo:
storyblok/storyblok-nuxt#172 (comment)
Would be great if that worked because I'm trying to migrate a wordpress site that has wp shortcodes embedded in the content.
I want to try and transform those into storyblok components.

@SebbeJohansson
Copy link
Owner

Hm okay interesting. Since i am using useStoryblokApi().richTextResolver.render(props.blok.text)) and not https://github.com/m4rvr/storyblok-rich-text-renderer (since it cant handle ssr with pretender correctly) or similar to render I would have to do it myself.

Here you can see that it completely removes the blok node:
image

I didn't have much time to look at this today, but I have a work in progress version:

<script setup lang="ts">
import { Richtext } from 'storyblok-js-client';

const props = defineProps({ blok: Object });
const nuxtApp = useNuxtApp();
const textObject = { ...props.blok.text };
const nodes = [];
Object.entries(textObject.content).forEach(([key, node]) => {
  if (node.type === 'blok') {
    const blok = {
      content: node.attrs?.body?.[0],
    };
    nodes.push({
      key,
      type: 'blok',
      content: {
        blok,
      },
    });
  } else {
    nodes.push({
      key,
      type: 'html',
      content: nuxtApp.$formatRichText(useStoryblokApi().richTextResolver.render({
        type: 'doc',
        content: [
          node,
        ],
      } as Richtext)),
    });
  }
});
</script>

<template>
  <div v-editable="blok" class="text">
    <div v-for="node in nodes" :key="node.key">
      <component
        :is="$resolveStoryBlokComponent(node.content.blok)"
        v-if="node.type === 'blok'"
        :blok="node.content.blok.content"
      />
      <div v-else v-html="node.content" />
    </div>
  </div>
</template>

<style>
.text img {
  max-width: 100%;
}
</style>

What I do:
I loop through all the nodes in the richtext. For each node I add it to an array representing the finished content. For the nodes that is a blok, I add it to the array with the type "blok" and for the rest (that I assume is proper richtext nodes that the resolver can handle) I add to the array with type "HTML" and I also resolve the richText right away.
This means that I get an array of each "node" that I want to render in the correct order.

The finished code does this:
image
image

Let me know if any of this was confusing. I will most likely refactor this when I have more time and add it to my finished code in production.

@SebbeJohansson
Copy link
Owner

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants