docs

Component Instantiation Guide

Components serve as the core building blocks of OpenUI5 applications. This guide explains the various ways to instantiate components, when to use each approach, and how to migrate from older mechanisms to modern alternatives.

On this page:


Overview of Instantiation Mechanisms

OpenUI5 offers several mechanisms for component instantiation, each suited for different scenarios:


Component Factories

OpenUI5 provides two modern component factories:

This section outlines the usage of the Component.create() API, as it is the most flexible and versatile way to create a component instance. Keep in mind that the full responsibility for component orchestration and rendering lies with the application.

  1. Component.create()

    The static Component.create() factory allows you to pass the name of a component along with additional options like the URL for a manifest.json. The return value of this factory is a Promise that resolves with the final component instance once it is fully constructed.

    Note:

    For more information on the manifest, see Manifest First Function.

    // Basic factory call
    const oBasicComponent = await Component.create({
        name: "sap.my.component",
    });
    

    You can also pass a dedicated URL for the manifest.json to the factory function. In this case, the URL must point directly to the manifest.json and must be resolved by the caller:

    // Creating a Component with a manifest URL
    const oComponentWithManifestURL = await Component.create({
        name: "sap.my.component",
        manifest: "any/location/sap/my/component/manifest.json"
    });
    
  2. Component#createComponent()

    The Component#createComponent() factory is explained below in Nesting Components.


Choosing the Right Instantiation Mechanism

The table below shows the recommended approach for each scenario. We recommend initializing the first application component via the ComponentSupport in the initial HTML page. If needed, you can also create a component programmatically using the Component.create() factory method in combination with a ComponentContainer. All recommended approaches support optimized manifest-first loading.

Scenario Recommended Approach Reason
Initial application component `ComponentSupport` Declarative; internally creates a `ComponentContainer` and automatically loads the referenced component
Navigation-based component creation Routing definition in `manifest.json` Versatile declarative defintion of navigation targets; allows for seamless nesting of components. This approach is especially important when routing is used within nested components, as it prevents conflicts that could arise when multiple components react to the same browser hash change.
Nested/reuse components `ComponentContainer` with `usage` Required for rendering a component; allows for automatic lifecycle management. Nested components can use their own routing to create further nested components \(see navigation-based component creation\).
Programmatic *reuse* component creation `Component#createComponent()` Asynchronous factory; allows to manually orchestrate the loading of a nested reuse component defined in the respective component instance's `manifest.json` \(via `sap.ui5/componentUsages`\). The newly created component is automatically marked as owned by its parent component, which allows for additional manifest-driven extensions.
Programmatic component creation `Component.create()` Asynchronous factory; allows to manually orchestrate the loading

Caution:

Do not use deprecated legacy mechanisms! For completeness, we mention the deprecated sap.ui.component() synchronous factory function. We strongly advise against using this function.

The modern approaches offers several significant advantages:


Initial Components

The following sections outline the recommended ways for instantiating the initial application component. For a detailed guide on creating nested components and subdividing your application, see Nesting Components.


ComponentSupport - Declarative Approach

The ComponentSupport module enables declarative component instantiation directly in HTML, making it the recommended approach for initial application components.

Good to know:

For samples regarding the ComponentSupport, see Declarative API for Initial Components.

Setup and Usage

Enable ComponentSupport in your bootstrap:

<!-- index.html -->
<script id="sap-ui-bootstrap"
    src="resources/sap-ui-core.js"
    data-sap-ui-on-init="module:sap/ui/core/ComponentSupport"
    data-sap-ui-async="true"
    data-sap-ui-resource-roots='{ "my.app": "./" }'
    data-...="...">
</script>

You now can declaratively define components directly in HTML using data attributes on a container DOM element (in this sample a <div> element):

<!-- index.html -->
<body id="content" class="sapUiBody sapUiSizeCompact" role="application">
    <div data-sap-ui-component
        data-id="myRootComponentContainer"
        data-name="my.app"
        data-height="100%"
        data-settings='{ "id": "myRootComponent" }'
        data-handle-validation="true"
        data-...="...">
    </div>
</body>

For more information, see the API Reference: module:sap/ui/core/ComponentSupport.

Advanced Usage

For scenarios requiring a pre-initialization setup, you can use a dedicated init module and manually load the ComponentSupport. Once loaded, it automatically detects any declarative component definition in the HTML page’s DOM (see the sample above).

<script id="sap-ui-bootstrap"
    data-sap-ui-on-init="module:my/app/startupEfforts"
    ...>
</script>
// my/app/startupEfforts.js
sap.ui.define(["my/app/MyModule"], (MyModule) => {
    "use strict";
    // Execute prerequisite code, e.g. loading additional application data, connecting to back-end services, etc.
    MyModule.init().then(() =>
        sap.ui.require(["sap/ui/core/ComponentSupport"])
    );
});

ComponentContainer - Programmatic Approach

Sometimes you need to programmatically create a component and render it in a specific part of the application or HTML page. For these use cases, we provide a ComponentContainer control, which has a special component association that holds the reference to the component instance.

Note:

You cannot use placeAt() directly on components - they must always be wrapped in a ComponentContainer.

ComponentContainers offer several features:

Using ComponentContainers

Method 1: Container-managed component creation

// "ComponentContainer" required from module "sap/ui/core/ComponentContainer"
var oContainer = new ComponentContainer({
    name: "samples.components.sample",
    manifest: true
});
oContainer.placeAt("target");

Method 2: Pre-created component association

// "Component" required from module "sap/ui/core/Component"
// "ComponentContainer" required from module "sap/ui/core/ComponentContainer"
Component.create({
    name: "samples.components.sample",
}).then(function(oComponent) {
    // Note: the Component instance (oComponent) is only associated in the ComponentContainer, not aggregated!
    var oContainer = new ComponentContainer({
        component: oComponent
    });
    oContainer.placeAt("target");
});

Lifecycle Management

The ComponentContainer lets you define a lifecycle of a component and how it aligns with the lifecylce of the container.For more information, see the API Reference: sap.ui.core.ComponentLifecycle.

Note:

The default is sap.ui.core.ComponentLifecycle.Legacy.

// "ComponentContainer" required from module "sap/ui/core/ComponentContainer"
// "coreLibrary" required from module "sap/ui/core/library"
var oContainer = new ComponentContainer({
    name: "samples.components.sample",
    lifecycle: coreLibrary.ComponentLifecycle.Container,
    manifest: true
});

Nesting Components

Nesting components lets you subdivide your application into smaller, independent parts. Each part has its own dedicated set of dependencies and resources. For example, in a shop application that displays a list of products, the editing functionality should only be visible to administrators. It doesn’t need to be loaded for other users. Nested components help you decouple this functionality. This approach reduces the initial payload needed to start your main component, improving application startup performance and resource utilization.

You can nest components in these ways:


Manifest Configuration

Before configuring nested components via routing or instantiating them programmatically, declare them in the sap.ui5/componentUsages section of your parent component’s manifest.json:

{
    "sap.ui5": {
        "componentUsages": {
            "myreuse": {
                "name": "sap.reuse.component",
                "settings": {},
                "componentData": {},
                "lazy": false
            }
        }
    }
}

Configuration Options:


Routing With Nested Components

Nesting components with target-based navigation is the recommended way to achieve a separation of concerns. This approach is especially important when routing is used within nested components, as it prevents conflicts that could arise when multiple components react to the same browser hash change.

Using routing with nested components requires:

For more information, see Enabling Routing in Nested Components.

Routing Configuration (manifest.json):

Note:

The routing configuration also provides a "View" target type.

When multiple components have their own routing configuration, their individual routers coordinate hash access to prevent conflicts. This allows for sub-routing and ensures deterministic navigation across the component hierarchy.

For more information, see Routing Configuration.

{
    "sap.ui5": {
        "componentUsages": {
            "myreuse": {
                "name": "reuse.component",
                "lazy": false
            }
        },
        "routing": {
            "config": {
                "async": true
            },
            "routes": [{
                "name": "componentRoute",
                "pattern": "component",
                "target": "componentTarget"
            }],
            "targets": {
                "componentTarget": {
                    "type": "Component",
                    "usage": "myreuse",
                    "options": {
                        // Additional component options
                    },
                    "containerOptions": {
                        // ComponentContainer options
                    }
                }
            }
        }
    }
}

Programmatic Instantiation

In certain scenarios, programmatic component instantiation is required, such as opening a dialog component when a user performs a specific action. The Component class provides a factory function to asynchronously create reuse components that are declared in the manifest. While this approach requires additional application code, it offers greater control and flexibility, allowing you to precisely orchestrate the loading and instantiation of nested components.

Simplified usage:

const oComponent = await this.createComponent("myreuse");

Extended usage:

const oComponent = await this.createComponent({
    usage: "myreuse",
    settings: {},
    componentData: {}
});

Adding the component to the control tree:

To add your newly created component into the control tree, you need to associate it with a ComponentContainer:

// associate the component in a ComponentContainer
const oContainer = new ComponentContainer({
    component: oComponent
});
// and place it into the control tree
myView.addContent(oContainer);

ComponentContainer with owner component:

Instead of calling the Component#createComponent factory on a component instance, you can directly create a ComponentContainer and reference the reuse component via its name declared in the manifest.json.

This approach only works if you ensure that the ComponentContainer is instantiated within the “owner scope” of the component defining the componentUsage. For more information, see The Owner Component.

For more information, see the usage options outlined in the API Reference for ComponentContainer and the API Reference for Component#runAsOwner used in the example below.

// Ensure that the ComponentContainer is created in the correct owner scope!
oMyAppComponent.runAsOwner(() => {
    const oContainer = new ComponentContainer({
        usage: "myreuse"
    })
    oContainer.placeAt("target");
})

Declarative Usage in XML Views

To declaratively create a component from within an XML view, simply place it in the XML DOM:

<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns:core="sap.ui.core" ...>
    <core:ComponentContainer usage="myreuse" manifest="true" />
</mvc:View>

Note:

Depending on how you create the XML view, you may need to ensure that the owner scope is correctly set. For more information, see The Owner Component.

If your view is created programmatically and not via a routing target, you need to wrap the view’s factory call in a corresponding Component#runAsOwner call:

oMyAppComponent.runAsOwner(() => {
    const oMyView = await XMLView.create(...);
    // add the view to the control tree
});

Migration Guidelines

The OpenUI5 framework is continuously evolving to leverage modern web standards and browser capabilities while maintaining backward compatibility. To keep your applications performant, secure, and future-ready, migrating from legacy component APIs to modern alternatives is essential.

Note:

For comprehensive guidance on modernizing your codebase, see Best Practices for Developers, which provides detailed recommendations for legacy-free OpenUI5 development.


Legacy sap.ui.component() Factory

The legacy sap.ui.component() factory function creates components synchronously, which blocks the UI thread and violates Content Security Policy requirements. Migrating to asynchronous alternatives is essential for modern OpenUI5 development.

Legacy approach:

createContent: function() {
    var oReuseComponent = sap.ui.component({
        "name": "sap.reuse.component"
    });
}

Modern approach:

createContent: function() {
    var oReuseComponentPromise = this.createComponent({
        "usage": "reuse"
    });
}

Legacy Component Dependencies

Legacy definition in manifest.json:

{
    "sap.ui5": {
        "dependencies": {
            "components": {
                "sap.reuse.component": {}
            }
        }
    }
}

Modern definition in manifest.json:

{
    "sap.ui5": {
        "componentUsages": {
            "reuse": {
                "name": "sap.reuse.component",
                "lazy": false
            }
        }
    }
}

Best Practices

  1. Always use asynchronous APIs - use Component.create() instead of sap.ui.component().
  2. Prefer ComponentSupport for initial components over manual ComponentContainer creation.
  3. Declare reuse components in componentUsages rather than in dependencies.
  4. Enable async routing in all components when using nested component routing.
  5. Use routing with nested components for nested components that define their own routing.
  6. Use proper lifecycle management via the ComponentContainer’s lifecycle property.
  7. Leverage manifest-first loading for optimal performance.

Related Information

Declarative API for Initial Components

Enabling Routing in Nested Components

Descriptor Dependencies to Libraries and Components

The Owner Component

API Reference: sap.ui.core.Component

API Reference: sap.ui.core.ComponentContainer

API Reference: ComponentSupport