Components Ready
Table of Contents
Since the components are loaded lazily, it might be hard to tell when they are ready if you rely on them
programmatically. To solve that we provide the componentsReady
function which returns a promise that resolves as soon
as all currently used components are loaded and ready to use.
The resolved value is a number with the amount of ready components.
If the DOM changes later on you can call it again to know when the new components are loaded.
The componentsReady
function is provided as part of the following components packages:
@porsche-design-system/components-js
@porsche-design-system/components-angular
@porsche-design-system/components-react
@porsche-design-system/components-vue

Before proceeding, consider using the whenDefined
function from the CustomElementRegistry API.
If you're unsure, review our comparison and example usage for guidance.
Basic Example#
componentsReady
is quite flexible. You can call it wherever and as often as you like.
By default, it uses the current document's body
element to look for any web component of the Porsche Design System.
import { componentsReady } from '@porsche-design-system/components-{js|angular|react|vue}';
const doSomeStuff = async () => {
await componentsReady();
};
Advanced Example#
In case you want to limit the search radius of componentsReady
you can pass any HTMLElement
as a parameter.
This is useful when you want to show a loading indicator for only a part of your application's interface, e.g. the
sidebar and only care about components inside.
You can also specify the readyState
that the
document or component should reach before the promise resolves. The default readyState
is set to complete
, but you
can adjust it to other states like interactive
or loading
based on your requirements.
import { componentsReady } from '@porsche-design-system/components-{js|angular|react|vue}';
const initSomeSidebar = async () => {
const sidebarEl = document.querySelector('.sidebar');
let showSpinner = true;
await componentsReady(sidebarEl, 'interactive');
showSpinner = false;
};
Testing#
In this section you can find basic examples for the default test setups of each framework.
Vanilla JS: jest
, jsdom
with @testing-library
Angular: jasmine
, karma
with TestBed
React: jest
, jsdom
with @testing-library/react
Other Angular setups can be found further down.

All test environments that don't use a real browser typically run in jsdom which requires our @porsche-design-system/components-{js|angular|react|vue}/jsdom-polyfill
subpackage in order to have real working Porsche Design System components.
Without it, you are just rendering "dead" component markup without any functionality.
Angular Jest with TestBed
Setup: jest
, jsdom
with TestBed
Angular Jest with Testing Library
Setup: jest
, jsdom
with @testing-library/angular
Component Readiness Explained#
componentOnReady
(Stencil): Resolves when a single Stencil
component and its internal DOM are fully initialized. Ideal for ensuring readiness before operations.
componentsReady
(PDS): A Porsche Design System (PDS) utility that
wraps componentOnReady
, resolving when all currently used PDS components are fully loaded and operational.
whenDefined
(Web API):
Resolves when a custom element is registered in the browser, ensuring availability but not readiness.
Basic Example (When Defined)#
This example demonstrates how to use the whenDefined
function to track and wait for the definition of all custom
elements within the document's body. The function returns the number of elements that were initially undefined but have
now been defined.
const whenDefined = async (el: HTMLElement = document.body): Promise<number> => {
const undefinedElements = el.querySelectorAll(':not(:defined)');
const promises = Array.from(undefinedElements).map((el) => customElements.whenDefined(el.localName));
try {
await Promise.all(promises);
return promises.length;
} catch (err) {
console.error('[CustomElementRegistry: whenDefined()]', err);
return 0;
}
};
const doSomeStuff = async () => {
await whenDefined();
};