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.