DEV Community

Cover image for Sitecore Hackaton 2025
Sebastián Aliaga
Sebastián Aliaga

Posted on

Sitecore Hackaton 2025

Building a Sitecore XM Cloud Component Creator: My Second Hackathon Experience

A few weeks ago, I participated in my second Sitecore Hackathon with team "404 Bugs Not Found". Our mission? Create a VSCode extension that streamlines component creation and deployment in Sitecore XM Cloud. Here's a deep dive into our technical solution.

The Technical Challenge

Sitecore XM Cloud development involves several manual steps when creating components:

  • Creating the component's TSX/JSX file
  • Setting up the component's template in Sitecore
  • Creating placeholder settings
  • Configuring the component rendering
  • Linking everything together

We aimed to automate this entire process through a VSCode extension.

Core Technical Features

1. Interactive UI with WebView

We created a sophisticated form interface using VSCode's WebView API. Here's a snippet of our form structure:

<div class="form-group">
    <label for="componentName">Component Name</label>
    <input required type="text" id="componentName" placeholder="Enter component name">
</div>

<div class="form-group">
    <label for="componentType">Component Type</label>
    <select id="componentType">
        <option value="none">None</option>
        <option value="withDatasourceCheck">With Datasource Check</option>
        <option value="withDatasourceRendering">With Datasource Rendering</option>
    </select>
</div>
Enter fullscreen mode Exit fullscreen mode

2. Dynamic Field Management

One of our most interesting features is the dynamic field management system:

function addField() {
    const fieldsContainer = document.getElementById('fields');
    const fieldRow = document.createElement('div');
    fieldRow.className = 'field-row';
    fieldRow.innerHTML = `
        <input type="text" placeholder="Field name" required>
        <select>
            <option value="SingleLineText">Single Line Text</option>
            <option value="RichText">Rich Text Field</option>
            <option value="LinkField">Link Field</option>
            <option value="ImageField">Image Field</option>
            <option value="Checkbox">Checkbox</option>
            <option value="MultilineText">Multiline Text</option>
        </select>
        <div class="checkbox-wrapper">
            <input type="checkbox" id="required-${fieldCount}">
            <label for="required-${fieldCount}">Required</label>
        </div>
        <button onclick="this.parentElement.remove()" title="Remove field">×</button>
    `;
    fieldsContainer.appendChild(fieldRow);
}
Enter fullscreen mode Exit fullscreen mode

3. GraphQL Integration

The most challenging part was integrating with Sitecore's GraphQL API. Here's our template creation mutation:

mutation {
    createItemTemplate(
        input: {
            name: "${templateName}",
            parent: "${templateParent}",
            createStandardValuesItem: true,
            sections: {
                name: "Content",
                fields: [
                    {
                        name: "${field.label}",
                        type: "${field.value === "RichText" ? "Rich Text" : field.value}",
                        required: ${field.isRequired}
                    }
                ]
            }
        }
    ) {
        itemTemplate {
            templateId
            name
            ownFields {
                nodes {
                    name
                    type
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

4. Placeholder Management

We implemented a sophisticated placeholder system that handles both static and dynamic placeholders:

function updatePlaceholderKey(select) {
    const row = select.closest('.placeholder-row');
    const keyInput = row.querySelectorAll('input[type="text"]')[1];
    const currentKey = keyInput.value;

    if (select.value === 'dynamic') {
        if (!currentKey.endsWith('-{*}')) {
            keyInput.value = currentKey + '-{*}';
        }
    } else {
        if (currentKey.endsWith('-{*}')) {
            keyInput.value = currentKey.slice(0, -4);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Rendering Creation

The final piece was creating the rendering with proper placeholder references:

const renderingQuery = `
    mutation {
        createItem(
            input: {
                name: "${sitecoreName}",
                templateId: "{04646A89-996F-4EE7-878A-FFDBF1F0EF0D}",
                parent: "${renderingParent}",
                language: "en",
                fields: [
                    { name: "componentName", value: "${codeName}" }
                    ${placeholderIds.length > 0
                        ? `, { name: "Placeholders", value: "${placeholderIds.join("|")}" }`
                        : ""
                    }
                ]
            }
        ) {
            item {
                itemId
                name
                path
            }
        }
    }`;
Enter fullscreen mode Exit fullscreen mode

Technical Challenges Overcome

  1. Field Type Mapping: We had to carefully map our field types to Sitecore's expected formats:
switch (field.value) {
    case "RichText":
        return "Rich Text";
    case "SingleLineText":
        return "Single-Line Text";
    case "MultilineText":
        return "Multi-Line Text";
    case "ImageField":
        return "Image";
    case "LinkField":
        return "General Link";
    case "Checkbox":
        return "Checkbox";
    default:
        return field.value;
}
Enter fullscreen mode Exit fullscreen mode
  1. Placeholder Reference Management: Ensuring proper linking between placeholders and renderings required careful handling of IDs and proper mutation ordering.

  2. Type Safety: Implementing proper TypeScript interfaces and type checking throughout the extension.

Future Technical Enhancements

  1. Support for more complex field types and configurations
  2. Enhanced template inheritance capabilities
  3. Integration with Sitecore CLI
  4. Support for component variants
  5. Automated testing infrastructure

Conclusion

This hackathon pushed us to create a solution that not only works but is also maintainable and extensible. The combination of VSCode's WebView API, TypeScript's type safety, and Sitecore's GraphQL API allowed us to create a tool that significantly improves the developer experience.

The code is open source and available for the community to use and enhance. We're looking forward to seeing how it evolves and helps other Sitecore developers streamline their workflow.

Repository
Video Demo


Are you interested in contributing to this project? Check out our repository and let's make Sitecore development even better together!

Top comments (0)