Create Content Element

This guide demonstrates how to implement a new custom Content Element.

Prepare Content Element in the TYPO3 Backend

It is assumed that you have already prepared your Content Element in the TYPO3 Backend. In this guide, we will use the example of a custom Content Element of type image_with_description.

Here's an example response:

{
   "id":108,
   "type":"image_with_description",
   "colPos":0,
   "categories":"",
   "appearance":{
      "layout":"default",
      "frameClass":"default",
      "spaceBefore":"",
      "spaceAfter":""
   },
   "content":{
      "header":"What is Lorem Ipsum?",
      "headerLink":"https://www.lipsum.com/",
      "bodytext":"<p><strong>Lorem Ipsum</strong> is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>",
      "assets":[
         {
            "publicUrl":"https://api.pwa-demo.ddev.site/fileadmin/introduction/images/typo3-book-backend-login.png",
            "properties":{
              // not relevant
            }
         }
      ]
   }
}

You should be able to see a JSON response on your frontend. This means that nuxt-typo3 does not recognize your new Content Element and it is attempting to render it using the T3CeDefault component.

Create new component file

Let's create a new Vue.js component file with the same name as your Content Element type - in our case, image_with_description.

Each Content Element name should be prefixed with T3Ce. This allows us to determine which components are intended to be used as Content Elements.

Create a new file T3CeImageWithDescription.vue in the components/global directory.

T3CeImageWithDescription.vue
<template>
  <div>Custom Content element</div>
</template>

Test it to see if the new Content Element is visible on the Frontend.

Why should I keep my Content Element (CE) components in the global directory? There are other possibilities. Read more about components overriding.

Provide Props Interface

When your component is properly registered in the frontend application, you can handle the Props interface. Based on our image_with_description, these are the fields you will need to handle in your Content Element:

  • header
  • headerLink
  • bodytext
  • assets

Most Content Elements use common properties such as header, headerLayout, etc. That's why, while working on your Content Element, you can extend our T3CeBaseProps interface.

Edit T3CeImageWithDescription.vue and add <script> section:

T3CeImageWithDescription.vue
<script setup lang="ts">
import type { T3CeBaseProps, T3File } from '@t3headless/nuxt-typo3';

interface T3CeImageWithDescription extends T3CeBaseProps {
    bodytext: string,
    assets?: T3File[]
}
const props = withDefaults(defineProps<T3CeImageWithDescription>(), {
  bodytext: ''
})
</script>

Provide Template

Now you are able to use all defined properties in your template.

Edit T3CeImageWithDescription.vue and add <template> section:

T3CeImageWithDescription.vue
<template>
    <h2> {{ header }} </h2>
    <T3HtmlParser :content="bodytext"/>
    <img v-if="assets?.[0]" :src="assets[0].publicUrl">
</template>
If you want to render HTML Content from RTE, then you should use our T3HTMLParser to parse it correctly and handle internal links.