Sitecore Full-stack XM Cloud Development Guide Tutorial - Component creation

S

This is the last tutorial of the Full-stack XM Cloud Development Guide.

So we've covered 2 parts: How to Set Up Docker for XM Cloud Dev and Full-Stack Local XM Cloud Dev Environment Tutorial.

This Full-stack XM Cloud Development Guide is written by Yaochang Liu, a Sitecore Content Hub Administrator Certification winner and experienced developer from Qedge. Yaochang, we really appreciate your effort!

So, let's get started.

Component Development Process

๐Ÿ“˜Basic Process

1. Create a Datasource Template

 /sitecore/templates/Project/Components/Demo/Demo1Component
Full-stack XM Cloud Development Guide

2. Create a Parameters Template

Create a Parameters Template and build Standard Values

/sitecore/templates/Project/Components/Demo/Rendering Parameters/Demo1 Parameters
Create a Parameters Template
Note: Select at least 3 Base templates shown above, and additional ones can be added based on requirements.

3. Create a JSON rendering

/sitecore/layout/Renderings/Project/Play/Demo Component/Demo1

Edit the following fields:

Create a JSON rendering

4. Create Available Rendering

Add the JSON Rendering created in Step 3 to the corresponding Available Rendering

 /sitecore/content/Play/Play/Presentation/Available Renderings/Demo Component
Create Available Rendering

5. Create Variants

 /sitecore/content/Play/Play/Presentation/Headless Variants/Demo1

6. Create Variant Definition

/sitecore/content/Play/Play/Presentation/Headless Variants/Demo1/Default
Create Variant Definition

7. FE coding

The file name should be consistent with the Component Name in step 3 of the JSON rendering and should not contain any spaces.

FE coding
FE coding -  tsx
import React from 'react';
import {
    Image as JssImage,
    Text,
    ImageField,
    TextField,
} from '@sitecore-jss/sitecore-jss-nextjs';

interface Fields {
    Image: ImageField;
    Title: TextField;
}

type Demo1Props = {
  params: { [key: string]: string };
  fields: Fields;
};

const Demo1DefaultComponent = (props: Demo1Props): JSX.Element => (
    <div className={`component promo ${props.params.styles}`}>
        <div className="component-content">
            <span className="is-empty-hint">Demo1</span>
        </div>
    </div>
);

export const Default = (props: Demo1Props): JSX.Element => {
    const id = props.params.RenderingIdentifier;
    if (props.fields) {
        return (
            <div className={`component promo ${props.params.styles}`} id={id ? id : undefined}>
                <div className="component-content">
                    <div className="field-promoicon">
                        <JssImage field={props.fields.Image} />
                    </div>
                    <div className="promo-text">
                        <div>
                            <div className="field-promotext">
                                <Text field={props.fields.Title} />

                            </div>
                        </div>

                    </div>
                </div>
            </div>
        );
    }

    return <Demo1DefaultComponent {...props} />;
};

Note: Ensure that the export const Default is consistent with the name "Default" in step 6 of the Variant Definition.

โœˆ๏ธAdvanced Techniques

Nest Components within Components (static placeholder) and/or using multi-variant.

1. Create a Placeholder

/sitecore/layout/Placeholder Settings/Project/Play/Demo1
Create a Placeholder

2. Update Rendering

Modify the Layout Service Placeholders in the JSON Rendering.

Select the Placeholder added in the previous step.

Update Rendering

3. Set placeholder restrictions

Add placeholder to the appropriate path

 /sitecore/content/Play/Play/Presentation/Placeholder Settings/Demo1/Demo1
Set placeholder restrictions

4. Add a Variant Definition

/sitecore/content/Play/Play/Presentation/Headless Variants/Demo1/WithSub
Add a Variant Definition

5. FE coding

import React from 'react';
import {
    Image as JssImage,
    Text,
    ImageField,
    TextField,
    Placeholder,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { ComponentProps } from 'lib/component-props';

interface Fields {
    Image: ImageField;
    Title: TextField;
}

type Demo1Props =
    ComponentProps & {
        fields: Fields;
    };

const Demo1DefaultComponent = (props: Demo1Props): JSX.Element => (
    <div className={`component promo ${props.params.styles}`}>
        <div className="component-content">
            <span className="is-empty-hint">Demo1</span>
        </div>
    </div>
);

export const Default = (props: Demo1Props): JSX.Element => {
    const id = props.params.RenderingIdentifier;
    if (props.fields) {
        return (
            <div className={`component promo ${props.params.styles}`} id={id ? id : undefined}>
                <div className="component-content">
                    <div className="field-promoicon">
                        <JssImage field={props.fields.Image} />
                    </div>
                    <div className="promo-text">
                        <div>
                            <div className="field-promotext">
                                <Text field={props.fields.Title} />

                            </div>
                        </div>

                    </div>
                </div>
            </div>
        );
    }

    return <Demo1DefaultComponent {...props} />;
};

export const WithSub = (props: Demo1Props): JSX.Element => {
    const id = props.params.RenderingIdentifier;
    if (props.fields) {
        return (
            <div className={`component promo ${props.params.styles}`} id={id ? id : undefined}>
                <div className="component-content">
                    <div className="field-promoicon">
                        <JssImage field={props.fields.Image} />
                    </div>
                    <div className="promo-text">
                        <div>
                            <div className="field-promotext">
                                <Text field={props.fields.Title} />
                                <h1>VVV</h1>
                                <div className="row">
                                     //The following is for nesting components
                                    <Placeholder name="demo1" rendering={props.rendering} />
                                </div>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        );
    }

    return <Demo1DefaultComponent {...props} />;
};

๐Ÿ“ Styles

1. Add Styles

Add the JSON Rendering to the Allowed Renderings of the corresponding Style

/sitecore/content/Play/Play/Presentation/Styles/Demo1/Demo1 large
Add Styles

2. FE coding

Add scss

Add scss
@import "@sass/abstracts/vars";
@import "@sass/abstracts/mixins";

.large-css {
    max-width: 960px;
    padding: 0;
    border-top-width: 3px;
    border-style: solid;
    overflow: visible;
    background-color: red;
}

3. Preview in Pages

Preview in Pages

Index