Ripple Framework

Adding a new dynamic component

Learn how to add a new dynamic page component to a content type

See key concepts - dynamic components for a conceptual overview of what dynamic components are and how they are used within the SDP platform.

Dynamic components comprise of the following elements:

  • A mapping function that will map the raw drupal api response to a Vue component and the props to pass to that Vue component
  • A Vue component that will render the component
  • A list of 'includes' to send to Drupal JSON API (See drupal docs for Includes)
  • A list of content types that the dynamic component can be added to

Each dynamic component then needs to be registered against the name of the paragraph in Drupal.

#Registering the dynamic component

Dynamic components need to registered inside a Nitro Plugins. Nitro is the server engine used in Nuxt 3.

Nitro Plugins can be added in the /server/plugins folder in your project.

Use the setDynamicComponent method to register your component.

setDynamicComponent takes the following parameters:

  • name of the component in Drupal (paragraph name)
  • the mapping function, includes and list of content types
// /server/plugins/my-content-type.ts

export default defineNitroPlugin(async (nitroApp: NitroApp) => {
  nitroApp.tide?.pageApi.setDynamicComponent('paragraph--my_dynamic_component', {
    mapping: (field) => { ... },
    includes: [ ... ],
    contentTypes: [ ... ]
  })
})

The individual elements of a dynamic component are covered below.

#The mapping function

The mapping function takes the raw response from the drupal JSON API and returns a standard structure that ultimately ties the dynamic component with a Vue component.

import { TideDynamicPageComponent } from '@dpc-sdp/ripple-tide-api/types'

interface IMyDynamicComponentProps {
  someProp1: boolean,
  someProp2: string
}

const mappingFunction = (field): TideDynamicPageComponent<IMyDynamicComponentProps> => {
  return {
    // This should be the name to the Vue component you created
    component: 'MyDynamicComponent',

    // Always include a unique id
    id: field.drupal_internal__id.toString(),

    // Some components have titles above them, which you can add here. This is optional
    title: field.field_paragraph_title,

    // These props will be passed to `MyDynamicComponent`
    props: {
      someProp1: false,
      someProp2: field.field_paragraph_description
    }
  }
}

#The Vue component

Create a Vue component that will render your dynamic component.

This component will be rendered each time your component appears on a page and will receive any props that were specified from the mapping function.

Important note: For this to work, your component needs to be registered globally. The simplest way to do this is to add the component to the /components/global folder in your layer.

Because they are global it's also important to choose non generic names so that they don't clash and overwrite other dynamic components

// /components/global/MyDynamicComponent.vue

<script setup lang="ts">
defineProps<{
  someProp1: boolean,
  someProp2: string
}>()
</script>

<template>
  <div>
    {{someProp2}}
  </div>
</template>

#The list of includes

Each dynamic component should specify an array of 'includes' that it needs in order to function properly.

const includes = [
  'field_landing_page_component.field_paragraph_accordion'
]

#The list of content types

Each dynamic component should specify an array of 'content types' that the dynamic component can appear on.

const contentTypes = [
  'landing_page',
  'some_content_type'
]

Propose a change to this page on GitHub.