Create the component files

A component is made up of a set of files organized into a directory, with at least a manifest.json file and a JavaScript file.

For a given component, all the files must be in the same directory as manifest.json file, or in a child directory of that directory.

A set of components is generally stored as multiple directories and often stored in a single git repository.

In this tutorial a Hello World component will be created.

As part of this tutorial, the Hello World component will be deployed to a Squiz DXP instance.

To distinguish this component from other components that may be deployed to this Squix DXP instance, append your initials to the component names and other objects.

In the material following, the strings ab and AB — as used in sample filenames and sample field names in `manifest.json — should be substituted with your initials.

Create the component file structure

To create the component file structure:

  1. create a directory, components.

    mkdir components
  2. change into the components directory.

    cd components
  3. create a directory named for the component to be created.

    mkdir hello-world-ab
  4. change into the hello-world-ab directory.

    cd hello-world-ab
  5. create four text files: manifest.json, main.mjs, README.md, and preview-wrapper.html.

    touch manifest.json main.mjs README.md preview-wrapper.html

    The JavaScript file uses the mjs filename extension to explicitly indicate the file’s content uses the ES Module syntax.

    The plain js filename extension can be used if preferred.

    If so preferred, the same filename extension must be used in manifest.json when referencing this file.

The completed file structure is as follows:

├── components
│   └── hello-world-ab
│       ├── main.mjs
│       ├── manifest.json
│       ├── preview-wrapper.html
│       └── README.md

Set-up manifest.json

To setup manifest.json for use by the component

  1. Open the file in a text editor.

  2. Copy-and-paste the following JSON-formatted data into the file.

    {
        "$schema": "http://localhost:3000/schemas/v1.json#", (1)
        "version": "0.0.1", (2)
        "type": "edge", (3)
        "name": "hello-world-ab", (4)
        "displayName": "Hello World (AB)", (5)
        "description": "Hello World test component for AB.", (6)
        "namespace": "ab-components" (7)
    }
    1 The location of the JSON schema. This schema defines the set of allowed and required fields for the manifest.json file.

    If you use a JavaScript- and JSON-aware text editor, this gives you code completion suggestions for the various allowed values in the manifest’s fields.

    1 The version field.

    The version number value must be incremented every time you deploy the component to your Squiz DXP instance. Versions are immutable and cannot be redeployed over the same version.

    We recommend Semantic Versioning.

    1 The component type.

    The value for this key must be edge.

    1 The component name.

    This should always be in lower case, and without spaces.

    1 The component’s display name.

    This key value can (and generally should) be in mixed case and use spaces.

    1 The component’s description.

    One to two sentences describing the component’s purpose and utility.

    1 The component’s namespace.

    This is used to distinguish between similarly named components that may be shared across multiple systems.

    For example, a Squiz-produced accordion component that might conflict with a customer-built accordion component.

Set-up main.mjs

JavaScript files are used to render components.

And many components have only one JavaScript file.

It is possible, however, for a component to consist of multiple JavaScript files. For example, one JavaScript file for each function in a component.

For this Hello World component add a basic output, to display a heading in HTML, which includes the output of the input field of the component.

To set-up main.mjs to do this:

  1. Open the file in a text editor.

  2. Copy-and-paste the following JavaScript code into the file.

    // MAIN FUNCTION
    
    export default {
        async main({ something }) {
          return `<h1>Hello World! ${something} </h1>`;
        },
      };

Reference the JavaScript function in manifest.json

The JavaScript function must be referenced in manifest.json.

Referencing the function tells the Component service to use that specific JavaScript code to render the component.

In this sample component the functions field references one function: the only function in the sample JavaScript file.

The functions field can, however, reference multiple functions.

This can be useful if you want to have, for example, both an html and a JSON view of your content, or if you want to create an interactive component that uses different JSON endpoints as mini APIs to load data.

To reference the JavaScript function in manifest.json

  1. Open the file in a text editor.

  2. add a comma — , — to the end of the last line of JSON data.

    That is turn

        "namespace": "ab-components"
    }

    into

        "namespace": "ab-components",
    }
  3. Copy-and-paste the following JSON-formatted data into the file.

    Paste the data between the last line of extant JSON data and the closing parenthesis.

        "mainFunction": "main",
        "functions": [
            {
                "name": "main",
                "entry": "main.mjs",
                "input": {
                    "type": "object",
                    "properties": {
                        "something": {
                            "type": "string"
                        }
                    },
                    "required": [
                        "something"
                    ]
                },
                "output": {
                    "responseType": "html"
                }
            }
        ]
  4. The edited manifest.json file should now be as follows:

    {
       "$schema": "http://localhost:3000/schemas/v1.json#(opens in a new tab)",
       "version": "0.0.1",
       "type": "edge",
       "name": "hello-world-ab",
       "displayName": "Hello World (AB)",
       "description": "Hello World test component for AB.",
       "namespace": "ab-components",
       "mainFunction": "main", (1)
       "functions": [
           {
               "name": "main", (2)
               "entry": "main.mjs", (3)
               "input": { (4)
                   "type": "object",
                   "properties": {
                       "something": {
                           "type": "string"
                       }
                   },
                   "required": [ (5)
                       "something"
                   ]
               },
               "output": { (6)
                   "responseType": "html"
               }
           }
       ]
    }
    1 The mainFunction name.

    This is used to render the component.

    1 The name field within the function.

    This must match the value of the mainFunction field.

    This tells the Component Service which function to use for the primary component rendering.

    1 The entry field.

    This specifies which JavaScript file to use.

    If you have named said JavaScript file main.js rather than main.mjs, make certain the value for this field is also main.js.

    1 The input field.

    This field define the component’s content model or data structure.

    This will be used to automatically generate the editing experience for the component in the Content Management capability.

    For this example, we define a single string, something.

    This is the input we reference in the Javascript file with ${something}.

    1 The required field.

    This specifies which input fields are required and is used to validate the editing form generated in the Content Management capability.

    The required field is mandatory.

    If a component does not have any required fields an empty array must be specified.

    1 The output field.

    This field specifies the responseType: either HTML or JSON.

    In this case, we set responseType to HTML because the component is rendering a front end.

Making component fields translatable

This tutorial does not cover content page translation.

However, to make a field available for content page translation, add the following key-value pair to that field.

"translatable": true

Enable local component testing

In production, components are deployed to the Matrix Content Management System and render content provided by editors in the Matrix Content Management System’s editing interface.

To enable developers to test components independently of the Content Management System there is a local preview system that allows for mocking-up data, and the outer HTML to provide context to the component.

These previews can also be deployed to the DXP, to allow stakeholders to browse them and preview different variations of a given component.

To add a preview to your component

  1. Open manifest.json in a text editor.

  2. add a comma — , — between the final closing bracket — ] — and the final closing parenthesis — }.

    That is turn

        ]
    }

    into

       ],
    }
  3. Copy-and-paste the following JSON-formatted data into the file.

    Paste the data immediately before the final closing parenthesis.

        "previews": {
            "default": { (1)
                "functionData": { (2)
                    "main": { (3)
                        "inputData": { (4)
                            "type": "inline", (5)
                            "value": {
                                "something": "Text supplied to previews function."
                            }
                        },
                        "wrapper": { (6)
                            "path": "preview-wrapper.html"
                        }
                    }
                }
            }
        }
    1 The name of the preview.
    2 functionData provides multiple named inputs for the component’s functions.
    3 main is the function name. It corresponds to the function in the manifest.json functions field.

    Provide mock data here for multiple functions in the component preview.

    1 inputData is the object that should match the input in your function.

    Use this to provide example values for inputs to the function.

    1 type is the input type.

    This can take one of two values: inline or file.

    inline uses the value field to provide the mocked-up data directly

    file sources the mocked-up data from an external json file.

    1 wrapper is the html wrapper used to wrap the component when it is displayed.

    Use it to add necessary html context, or global CSS and JavaScript includes.

  4. The edited manifest.json file should now be as follows:

    {
       "$schema": "http://localhost:3000/schemas/v1.json#(opens in a new tab)",
       "version": "0.0.1",
       "type": "edge",
       "name": "hello-world-ab",
       "displayName": "Hello World (AB)",
       "description": "Hello World test component for AB.",
       "namespace": "ab-components",
       "mainFunction": "main",
       "functions": [
           {
               "name": "main",
               "entry": "main.mjs",
               "input": {
                   "type": "object",
                   "properties": {
                       "something": {
                           "type": "string"
                       }
                   },
                   "required": [
                       "something"
                   ]
               },
               "output": {
                   "responseType": "html"
               }
           }
       ],
       "previews": {
           "default": {
               "functionData": {
                   "main": {
                       "inputData": {
                           "type": "inline",
                           "value": {
                               "something": "Text supplied to previews function."
                           }
                       },
                       "wrapper": {
                           "path": "preview-wrapper.html"
                       }
                   }
               }
           }
       }
    }

Set-up preview-wrapper.html for local component preview

The previously created file, preview-wrapper.html, is used to preview the component locally.

To set this file up for this use:

  1. Open the file in a text editor.

  2. Copy-and-paste the following HTML markup into the file.

    <!DOCTYPE html>
    <html>
        <head></head>
        <body>
            [component://output] (1)
        </body>
    </html>
    1 The [component://output] tag is required.

    It is used to render the component by the local server.

    Otherwise, any valid HTML can be included in this file.

    This example uses the barest minimum required markup to produce a valid HTML file.

    In actual development, adding markup relevant to previewing the component is recommended.

    For example, consider adding the structural html used for pages on your site and replace any unique-to-a-given-page markup with the component tag.

Write the component README

The README file is the minimum documentation that should be included with a component.

For this tutorial, the file consists of a bare description.

To set this file up:

  1. Open the file in a text editor.

  2. Copy-and-paste the following HTML markup into the file.

    # Hello World (AB)
    
    A *Hello World* component from the Squiz DXP **Create a component** tutorial.