Vue Storefront is now Alokai! Learn More
Render component

Render component

This is a basic example of how you can create a render component.

Example of a render component in Vue.js

<template>
  <div>
    <component
      v-for="(component, index) in components"
      :key="`${component.componentName}-${index}`"
      :is="component.componentName"
      v-bind="component.props"
      class="content-block"
    />
  </div>
</template>

<script lang="ts" setup>
import { sdk } from '~/sdk.config';

const props = defineProps({
  content: {
    type: [Array, Object]
  }
});

const components = computed(() =>
  sdk.contentstack.utils.extractComponents(props.content)
);
</script>

Example of a render component in React.js

import React, { Fragment } from 'react';
import { sdk } from '~/sdk.config';

interface RenderComponent {
  componentName: string;
  props?: any;
}

export const componentsMap: Record<string, (props: any) => JSX.Element> = {
  Page,
  Banner
};

export default function RenderContent({
  content
}: {
  content: any[];
}): JSX.Element {
  return React.createElement(
    Fragment,
    {},
    sdk.contentstack.utils
      .extractComponents(content)
      .map(({ componentName, props }: RenderComponent) =>
        React.createElement(
          componentsMap[componentName] || NotRegisteredComponent,
          {
            ...props,
            key: componentName,
            componentName,
            content: <RenderContent content={props.content} />
          }
        )
      )
  );
}

function NotRegisteredComponent({ componentName }: { componentName: string }) {
  return <div>component {componentName} is not registered</div>;
}

/* demo components, remove them or move to separate files */
function Page({ name, url, content }: any): JSX.Element {
  return <div>{content}</div>;
}

/* demo components, remove them or move to separate files */
function Banner({
  title,
  subtitle,
  description,
  background,
  component,
  image,
  button_text,
  button_link
}: any): JSX.Element {
  return (
    <div>
      <h1>banner</h1>
      <p>title: {title}</p>
      <p>subtitle: {subtitle}</p>
      <p>description: {description}</p>
      <p>background: {background}</p>
      <p>component: {component}</p>
      <p>button_text: {button_text}</p>
      <p>button_link: {button_link}</p>
      <p>image: {image?.toString()}</p>
    </div>
  );
}