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.contentful.utils.extractComponents(props.content)
);
</script>

Example of a render component in React.js

import React, { Fragment } from 'react';
import type { RenderComponent } from '@vsf-enterprise/contentful-sdk';
import { sdk } from '~/sdk.config'

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.contentful.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>
  );
}