Skip to content
  • There are no suggestions because the search field is empty.

Custom layout: Core functionality explained

A detailed guide to the key features, variables, and templating structure available in custom layouts

If you’ve already created your first custom layout using our getting started guide, this article takes you one step further. Here, we break down the core building blocks of the Welcome app’s custom layout system, covering available variables, feature flags, templating syntax, and how to use widgets and components effectively.

Use this guide as your go-to reference when shaping more polished, feature-rich layouts.

Jump to


Handlebars templating

The Welcome app uses Handlebars as its templating engine. This allows you to:

  1. Insert variable values: {{variable}}
  2. Insert unescaped HTML: {{{variable}}}
  3. Use conditional logic: {{#if variable}}...{{else}}...{{/if}}
  4. Loop through arrays: {{#each array}}...{{/each}}
  5. Use custom helpers like audience targeting: {{#audience "guid"}}...{{/audience}}

Examples:

<!-- Display the username -->
<h1>Hello, {{username}}!</h1>

<!-- Insert an unescaped background URL -->
<div style="background-image: url({{{background}}})"></div>

<!-- Conditional rendering -->
{{#unless custom.greeting.hide}}
    <div class="greeting">
        <a365widget data-widget="greeting"></a365widget>
    </div>
{{/unless}}

<!-- Loop through content items -->
{{#each content}}
    <div class="item">
        <h2>{{title}}</h2>
        <p>{{description}}</p>
    </div>
{{/each}}

Variables

The following variables are available for use in your Handlebars templates.

Variable Type Description
webPartId string Unique identifier for the web part instance
userphoto string URL of the user's profile picture
username string Display name of the user
sourceUrl Nullable<string> Source URL if applicable
email string Email address of the user
audience string[] Array of audience GUIDs the user belongs to
background Nullable<string> URL of the background image
custom Record<BuiltInFeatures, Record<string, unknown>> Custom variables defined in the layout
content Slide[] Array of content slides to display

 

The content variable is an array of Slide objects with the following properties:

Property Type Description
id string Unique identifier for the slide
type string The type of content (from ContentSlide or ContentNews)
title string The title of the slide
subtitle string The subtitle or secondary text for the slide
background string The URL of the background image for the slide
ctaUrl string Call-to-action URL (link destination when slide is clicked)
ctaText string Call-to-action text (button or link text)
altText string Alternative text for the slide image (for accessibility)
custom Record<string, unknown> Optional custom properties specific to the slide

Features

Features are enabled via data attributes on the metadata template. Each feature adds specific functionality to your layout:

Feature Attribute Description
Greeting data-feature-greeting="true" Enables personalised greeting functionality
Time data-feature-time="true" Enables time display functionality
Weather data-feature-weather="true" Enables weather information functionality
Search data-feature-search="true" Enables search functionality
Slides data-feature-slider="true" Enables slides functionality (legacy)
Content data-feature-content="true" Enables content display (slides + news)
Background data-feature-background="true" Enables background image functionality

Widgets and components

Widgets are high-level UI elements that combine multiple components:

<a365widget data-widget="greeting"></a365widget>
<a365widget data-widget="time"></a365widget>
<a365widget data-widget="weather"></a365widget>
<a365widget data-widget="search"></a365widget>
<a365widget data-widget="content"></a365widget>

Components are lower-level UI elements that can be used independently:

<a365component data-component="greeting"></a365component>
<a365component data-component="photo"></a365component>
<a365component data-component="time"></a365component>

Best practices

  1. Keep only one instance of <style><script>, and <section> tags in the layout
  2. Avoid using HTML IDs; prefer classes instead
  3. If an ID is necessary, ensure it has a unique postfix, e.g., <div id="alert-{{webPartId}}"></div>
  4. Clean up resources in the onDispose() function to avoid memory leaks
  5. Use the .SCOPE class token to target elements outside the layout scope
  6. Only enable features that are actually used in the layout
  7. Use localized labels for better user experience
  8. Do not try to access or style elements outside of the template scope
  9. Avoid placing markup outside of template tags

➡️Next: Custom layout: Advanced functionality explained

⬅️Back: Custom layout: Getting started