-
Notifications
You must be signed in to change notification settings - Fork 3
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
Custom Component Resolver (Vue) #115
Comments
Hey there @babalugats76 thanks a lot for reaching out! I'm pretty happy to see more people using the package. Yes, we are currently working to integrate it into our ecosystem so you can use it from the Storyblok Vue and Nuxt SDK. About the custom component resolver, I have a snippet that would simplify your life big time, and its how currently we are implementing it on our Vue SDK import { StoryblokComponent } from '@storyblok/vue`
const componentResolver: StoryblokRichTextNodeResolver<VNode> = (
node: StoryblokRichTextNode<VNode>
): VNode => {
return h(
StoryblokComponent,
{
blok: node?.attrs?.body[0],
id: node.attrs?.id,
},
node.children
);
}; Instead of doing the component map manually, take advantage of the |
@alvarosabu Thank you so much for the helpful and detailed response. Much appreciated. I will take what you have provided and see if I can incorporate, dropping something similar into The reason why the code is so complicated is that I found that, when using the rich editor, |
Mmm, thats quite important feedback, do you have an example so I can reproduce where |
@alvarosabu Absolutemente. Add two consecutive components in the rich text editor using your preferred technique: This will result in story JSON similar to this: {
"story": {
"name": "Test",
"created_at": "2024-10-08T20:24:32.599Z",
"published_at": "2024-10-11T19:38:28.669Z",
"id": 12947931,
"uuid": "cbb00947-c9cd-4ef2-9f2d-0a3fdfe0e0cb",
"content": {
"_uid": "99560d3d-ad9d-4b76-8e9e-4ff96c96f1bb",
"body": [
{
"_uid": "1304e7f1-0cb5-4ca3-8b39-5f019a035f24",
"text": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"text": "Before components",
"type": "text"
}
]
},
{
"type": "blok",
"attrs": {
"id": "dabd9c69-02a7-46d4-8654-6fd381470dd1",
"body": [
{
"_uid": "i-da6aeb2b-e0fe-4764-a507-413e7484cf00",
"class": "",
"float": "",
"image": {
"id": 922456,
"alt": "A close up of a bunch of crayons",
"name": "",
"focus": "",
"title": "Crayons",
"source": "",
"filename": "https://a-us.storyblok.com/f/1021359/5616x3744/8a8956ad0e/crayons.jpg",
"copyright": "Photo by Alexander Grey on Unsplash",
"fieldtype": "asset",
"meta_data": {
"alt": "A close up of a bunch of crayons",
"title": "Crayons",
"source": "",
"copyright": "Photo by Alexander Grey on Unsplash"
},
"is_external_url": false
},
"width": "",
"height": "",
"rounded": "",
"component": "image",
"grayscale": false,
"responsive": true,
"_editable": "\u003C!--#storyblok#{\"name\": \"image\", \"space\": \"1021359\", \"uid\": \"i-da6aeb2b-e0fe-4764-a507-413e7484cf00\", \"id\": \"12947931\"}--\u003E"
},
{
"_uid": "i-dfcfac59-58a9-4ec3-9c02-9dce44f53800",
"class": "",
"float": "",
"image": {
"id": 922456,
"alt": "A close up of a bunch of crayons",
"name": "",
"focus": "",
"title": "Crayons",
"source": "",
"filename": "https://a-us.storyblok.com/f/1021359/5616x3744/8a8956ad0e/crayons.jpg",
"copyright": "Photo by Alexander Grey on Unsplash",
"fieldtype": "asset",
"meta_data": {
"alt": "A close up of a bunch of crayons",
"title": "Crayons",
"source": "",
"copyright": "Photo by Alexander Grey on Unsplash"
},
"is_external_url": false
},
"width": "",
"height": "",
"rounded": "",
"component": "image",
"grayscale": false,
"responsive": true,
"_editable": "\u003C!--#storyblok#{\"name\": \"image\", \"space\": \"1021359\", \"uid\": \"i-dfcfac59-58a9-4ec3-9c02-9dce44f53800\", \"id\": \"12947931\"}--\u003E"
}
]
}
},
{
"type": "paragraph",
"content": [
{
"text": "After components",
"type": "text"
}
]
}
]
},
"variant": "lavender",
"component": "rich-text",
"scaleText": true,
"_editable": "\u003C!--#storyblok#{\"name\": \"rich-text\", \"space\": \"1021359\", \"uid\": \"1304e7f1-0cb5-4ca3-8b39-5f019a035f24\", \"id\": \"12947931\"}--\u003E"
}
],
"component": "page",
"metaTitle": "This is the headline",
"metaDescription": "This is the byline",
"_editable": "\u003C!--#storyblok#{\"name\": \"page\", \"space\": \"1021359\", \"uid\": \"99560d3d-ad9d-4b76-8e9e-4ff96c96f1bb\", \"id\": \"12947931\"}--\u003E"
},
"slug": "test",
"full_slug": "test",
"sort_by_date": null,
"position": -140,
"tag_list": [],
"is_startpage": false,
"parent_id": null,
"meta_data": null,
"group_id": "1f75f5da-3105-452e-8cb5-73406e1b20c1",
"first_published_at": "2024-10-08T23:49:37.001Z",
"release_id": null,
"lang": "default",
"path": null,
"alternates": [],
"default_full_slug": null,
"translated_slugs": null
},
"cv": 1729449138,
"rels": [],
"links": []
} |
You have an example in playground |
@konstantin-karlovich-unbiased-co-uk Thank you for the feedback! However, I have already taken a look at that. To me, this is not an example of my use case nor does it show how to handle a true custom component. Keep in mind that in Vue Best I can tell, something outside the HTML spec needs to be shown in an example. Both one-off and consecutive, adjacent use of true custom components (non-HTML spec), including how to use a resolver, etc. I submitted this issue after having read and absorbed all the provided docs beforehand, including the Any help you can provide would be much appreciated, but please keep in mind that I provided a detailed example above that I would like addressed. If need be, I can create a reproduction. Just let me know. |
@babalugats76 Sorry, but, my comment was for @alvarosabu when he asked for an example when |
Summary
I am using Nuxt 3/Vue and need help migrating from renderRichText to storyblok/richtext, especially when it comes to the resolution and rendering of custom components contained within richtext fields.
I realize that this project is relatively new and probably still under heavy development, but, I have reviewed the playgrounds and available materials closely and my use case does not appear to be adequately addressed. IMHO, the Vue playground is missing key design patterns that would seemingly be part of any Vue implementation of the module.
Previous Solution
My previous solution utilized
renderRichText
and theVue3RuntimeTemplate
modules (for dynamic resolution).Work-In-Progress
I started by creating a composable to handle the application-wide rendering. I am specifically trying to address handling of
[BlockTypes.COMPONENT]
in the resolver and mapping of thecomponent
prop to the nested components, i.e.,Image
,Accordion
, andYouTube
:rich.ts
Then, I created a wrapper component that can be used to render the VNode returned from
RichTextRenderer.vue
In turn, I use this component downstream; for example, in a custom
Rich
Storyblok component:Rich.vue
Questions
What is the right way to resolve custom components?
Here is what I am doing which seems onerous and WAY more complicated (Array seems clunky, etc.) than before:
Is there a better way to do dynamic resolution?
I tried a lot of things, but ultimately had to ditch the use of
Vue3RuntimeTemplate
and instead had to hard code the dependencies:Any help/guidance would be greatly appreciated.
The text was updated successfully, but these errors were encountered: