PCF Manifest Configuration

Complete the full lesson to earn 25 points

Work through each section, then tap “Mark as Complete” on the last one.

Module: Extend the User Experience

Lesson: PCF Manifest Configuration

Introduction: Defining the Blueprint of Your Component

In the world of professional application development for platforms like Microsoft Dataverse or Power Apps, the Power Apps Component Framework (PCF) acts as the bridge between standard, out-of-the-box controls and the specific, high-fidelity user experiences that business requirements often demand. When you decide to build a custom component, you are essentially telling the platform, "I need a specific way for users to interact with data that standard inputs cannot provide." However, before you write a single line of TypeScript or CSS, you must define the contract between your code and the host environment. This contract is the PCF manifest file.

The manifest is an XML file—typically named ControlManifest.Input.xml—that serves as the blueprint for your component. It informs the platform about what your component does, what data it requires to function, and how it should behave within the context of a form, view, or dashboard. If you think of your component as a specialized machine, the manifest is the technical manual and the input/output interface specifications. Without a correctly configured manifest, the platform will not know how to load your component, what properties to pass into it, or how to handle the data it produces.

Understanding the manifest is arguably the most important skill for a developer working with PCF. While the logic inside your TypeScript files determines how the component looks and feels, the manifest determines whether the component can even exist in the environment. Misconfiguring this file leads to deployment errors, missing properties, or, worse, runtime failures that are notoriously difficult to debug. This lesson will walk you through every node, attribute, and best practice associated with the PCF manifest, ensuring you have the foundation to build stable, predictable, and professional custom controls.


Understanding the Control Manifest Structure

The manifest file follows a strict XML schema. While XML might feel dated compared to modern JSON-based configurations, it provides a rigid structure that allows the platform's build tools to validate your component before you ever attempt to deploy it. The root element of your manifest is the manifest tag, which contains the control element. Everything else—your properties, resources, and feature requirements—sits within these parent nodes.

The Core Elements

To build a functional component, you must understand the hierarchy of the manifest:

  1. Control: The top-level definition of your component. It includes the namespace, version, display name, and the type of component (field or dataset).
  2. Property-set: These are the inputs and outputs. They define the data that flows into your component from the Dataverse and the data that flows back out.
  3. Resources: This section tells the framework which files to load. You include your TypeScript entry point here, along with any CSS files, image assets, or third-party libraries.
  4. Feature-usage: If your component needs access to device capabilities (like the camera, location, or web API), you must declare those needs here.

Callout: Field vs. Dataset Components It is vital to distinguish between these two types early in your project. A Field Component is designed to replace a single input control (like a text box or a dropdown) on a form. It binds to a single attribute on a record. A Dataset Component is designed to visualize a collection of records, such as a grid, a chart, or a calendar view. The manifest structure for these two differs slightly, particularly in how they define the data source.


Step-by-Step: Configuring the Control Element

The control element is where you define the identity of your component. When you generate a new project using the Power Platform CLI (pac pcf init), this is partially pre-filled for you. However, you need to manage these attributes carefully as your project matures.

Namespace and Constructor

The namespace and constructor attributes are essential for the framework to instantiate your class. If you change your class name in your TypeScript code, you must update the constructor attribute in the manifest to match, or the application will fail to load the component.

<control namespace="MyCompany.Components" 
         constructor="CustomGauge" 
         display-name-key="Gauge_Display_Key" 
         description-key="Gauge_Desc_Key" 
         version="1.0.0" 
         control-type="standard">
  • namespace: Think of this as the unique identifier for your development organization. It prevents collisions with other components.
  • constructor: This must match the exported class name in your index.ts file.
  • display-name-key: This is used for localization. You do not put the actual name here; you put a key that maps to a resource file.
  • control-type: Usually set to standard. This indicates a standard PCF component.

Tip: Versioning Best Practices Always increment your version number (1.0.0, 1.0.1, etc.) whenever you make a change to the manifest or the logic. When you deploy, the platform uses this version to determine if an update is required. If you reuse the same version number, you may experience caching issues where the environment continues to use the old version of your code.


Defining Property-set: The Data Contract

The property-set section is where you define how your component talks to the data model. Each property represents a piece of data that the user can configure in the App Designer. For example, if you are building a color-picker component, you might have a property for the "Default Color" and another for the "Allow Custom Colors" toggle.

Each property needs a name, display-name-key, description-key, of-type, and usage.

Understanding Data Types (of-type)

The of-type attribute determines what kind of data the property expects. This is a strict contract. If you define a property as SingleLine.Text, you cannot pass a numeric value into it. Common types include:

  • SingleLine.Text: Standard strings.
  • Whole.None: Integers.
  • Currency: Money values.
  • Enum: A custom list of choices.
  • TwoOptions: Boolean true/false.

Usage: Input vs. Output

The usage attribute is either input or bound.

  • Input: The component reads the value but does not change it. This is perfect for configuration settings or read-only display labels.
  • Bound: The component reads the value AND can update it. When the user interacts with your control, the value is written back to the underlying Dataverse field.
<property-set name="inputValue" 
              display-name-key="Input_Value" 
              description-key="Input_Value_Desc" 
              of-type="SingleLine.Text" 
              usage="bound" 
              required="true" />

Warning: The "Required" Trap Setting required="true" makes the property mandatory in the App Designer. If a user tries to add your component to a form but forgets to map a field to a required property, the platform will prevent them from saving the form. Use this judiciously. If your component can function with default values, consider making properties optional.


Managing Resources: Loading Your Logic and Styles

The resources section is where you tell the browser which files to download. Your TypeScript code is compiled into a single file (usually bundle.js), which must be listed here. If you add CSS files or external libraries, they must be included in this section to be loaded correctly.

<resources>
  <code path="index.ts" order="1" />
  <css path="css/CustomGauge.css" order="1" />
  <resx path="strings/CustomGauge.1.resx" />
</resources>

Order Matters

The order attribute is significant when you have multiple files. The framework loads files in the order specified. If your CSS depends on a library, ensure the library is loaded first. However, in most modern PCF development, you will bundle your dependencies into your bundle.js using Webpack or similar tools, meaning you often only need to reference your main index.ts and your primary CSS file here.

Localization

The resx path allows you to provide a localized user experience. By creating .resx files, you can define your display names and descriptions in multiple languages. The platform automatically detects the user's language settings and displays the correct string. This is a requirement for any enterprise-grade component.


Feature Usage: Accessing External APIs

By default, PCF components run in a sandboxed environment for security. They cannot access the camera, the user's GPS, or perform arbitrary web requests. If your component requires these permissions, you must explicitly declare them in the feature-usage section of the manifest.

Available Features

  • WebAPI: Allows your component to make calls to the Dataverse Web API.
  • Device.captureAudio: Access to the microphone.
  • Device.captureImage: Access to the camera.
  • Device.getLocation: Access to GPS coordinates.
<feature-usage>
  <uses-feature name="WebAPI" required="true" />
  <uses-feature name="Device.getLocation" required="false" />
</feature-usage>

When you include these, the platform prompts the user for permission when the component is loaded. If you attempt to use these features without declaring them in the manifest, the browser will block the call, and your component will likely crash.


Best Practices for Manifest Configuration

Configuring a manifest is not just about getting it to work; it's about making it maintainable and professional. Follow these industry-standard practices to ensure your components are robust.

  1. Use Meaningful Names: Do not use generic property names like value1 or propA. Use descriptive names like targetColor or maxDisplayLimit. This helps other developers understand how to configure your component in the App Designer.
  2. Document with Keys: Always provide a description-key. When an administrator is configuring your component, they will see this description as a tooltip. A well-described property saves hours of support requests.
  3. Group Properties Logically: If you have many properties, group them by function. While the XML schema doesn't strictly force grouping, you can organize your manifest visually to make it easier to read.
  4. Keep Dependencies Minimal: Every resource you add increases the load time of your component. Only include the CSS and JS files you absolutely need.
  5. Validate Frequently: Use the pac pcf push or npm run build commands often. These commands validate your XML against the schema. If you make a typo in an XML tag, the build process will fail, providing you with immediate feedback.

Common Pitfalls and How to Avoid Them

Even experienced developers run into issues with the manifest. Being aware of these common traps can save you from late-night debugging sessions.

1. The Mismatching Constructor

One of the most frequent errors occurs when a developer renames their TypeScript class but forgets to update the constructor attribute in the manifest. The build process may succeed, but the component will fail to load in the browser with a "Control not found" or "Namespace mismatch" error. Always perform a global search for your class name when renaming files.

2. Incorrect Data Type Mapping

If you define a property as Whole.None but try to pass a string into it, the platform will handle it poorly. Sometimes it will truncate the value; other times, it will throw a runtime exception. Always ensure that the of-type attribute matches the exact data type you expect to receive in your updateView method.

3. Forgetting the Resource Path

If you add a new CSS file but forget to add it to the resources section, your component will look broken or unstyled. Because the build process doesn't always "see" your CSS files as dependencies of your TypeScript files, you must manually register them in the manifest.

4. Hardcoding Values

Avoid hardcoding configuration values inside your TypeScript logic. Instead, expose them as properties in the manifest. This allows users to change the behavior of your component (like changing a theme color or a threshold value) directly in the App Designer without needing you to recompile the code.

Callout: The Power of pac pcf init When starting a new component, always use the pac pcf init command. This creates the skeleton of your manifest with the correct XML namespaces and schema references. Manually creating the XML file is error-prone and often leads to missing essential tags required by the platform.


Comparing Property Types (Reference Table)

When designing your component, choose the correct of-type to ensure the platform provides the right input interface in the App Designer.

Property Type Use Case Dataverse Field Mapping
SingleLine.Text Simple text inputs, labels Text, Email, URL
Whole.None Counts, quantities Whole Number
Currency Financial values Currency
TwoOptions Toggles, switches Yes/No, Boolean
Enum Dropdowns, radio groups Option Sets
DateTime.DateOnly Calendars, date pickers Date Only
Decimal.Range Sliders, progress bars Decimal, Float

A Comprehensive Example: Building a Weather Widget

Let’s imagine we are building a weather widget that displays the temperature for a specific location. Our manifest needs to handle a location string, a toggle for Celsius/Fahrenheit, and access to the Web API to fetch weather data.

The Manifest (ControlManifest.Input.xml)

<?xml version="1.0" encoding="utf-8"?>
<manifest>
  <control namespace="WeatherApp" constructor="WeatherWidget" display-name-key="Weather_Name" description-key="Weather_Desc" version="1.0.0" control-type="standard">
    <property-set name="location" display-name-key="Location_Key" description-key="Location_Desc" of-type="SingleLine.Text" usage="bound" required="true" />
    <property-set name="useCelsius" display-name-key="Celsius_Key" description-key="Celsius_Desc" of-type="TwoOptions" usage="input" required="false" />
    <resources>
      <code path="index.ts" order="1" />
      <css path="css/WeatherWidget.css" order="1" />
    </resources>
    <feature-usage>
      <uses-feature name="WebAPI" required="true" />
    </feature-usage>
  </control>
</manifest>

Breakdown of the Example

  1. Namespace: WeatherApp keeps our code organized.
  2. Properties:
    • location: This is a bound property. If the user changes the location in our widget, we can update the underlying Dataverse field.
    • useCelsius: This is an input property. It’s a preference setting for the component, so we don't need to write it back to the database.
  3. Feature Usage: We enabled WebAPI because our component needs to make an external HTTP request to a weather service.
  4. Resources: We included the TypeScript entry point and the CSS for styling.

This configuration is clean, follows the rules, and provides a clear interface for anyone using this component in a Power App.


Troubleshooting: When Things Go Wrong

If you have configured your manifest and your component still isn't working, follow this checklist:

  1. Check the Browser Console: Open the browser's developer tools (F12). Often, you will see a detailed error message explaining exactly why the component failed to load, such as "Property X not found in manifest."
  2. Validate the XML: Use an online XML validator to ensure your file is well-formed. A missing closing tag or an unescaped character can break the entire file.
  3. Clear Cache: Sometimes the platform caches the old manifest. Try clearing your browser cache or performing a hard refresh (Ctrl+F5).
  4. Rebuild: Run npm run build again. Ensure that the bundle.js file is being generated and that it matches the path in your manifest.
  5. Check the pac version: Ensure you are using the latest version of the Power Platform CLI. Older versions may not support newer features or manifest attributes.

Summary and Key Takeaways

Configuring the PCF manifest is the foundational step in creating custom experiences for the Power Platform. It is the contract that defines how your component interacts with the world. By mastering this file, you ensure that your components are not only functional but also maintainable and professional.

Key Takeaways:

  • The Manifest is a Contract: It defines exactly what data enters your component and what permissions it requires. Treat it with the same care as your core logic.
  • Property Types Matter: Always match your of-type attributes to the actual data types you expect. This prevents runtime errors and ensures the App Designer provides the correct input controls to users.
  • Localization is Essential: Use resx files to support multiple languages. This is a hallmark of high-quality, enterprise-ready software.
  • Security First: Only enable the features you need in feature-usage. Over-provisioning access can lead to security vulnerabilities and unnecessary permission prompts for the end user.
  • Versioning is Mandatory: Always increment your version number with every change. This prevents frustrating cache-related bugs in production environments.
  • Documentation is a Feature: Use descriptive names and keys for your properties. A well-documented component is significantly easier for other team members to adopt and use correctly.
  • Validate Early and Often: Use the CLI tools to build and validate your manifest frequently. Catching an XML error during development is trivial; catching it after deployment is costly.

By internalizing these principles, you move from simply writing code that "works" to architecting components that are robust, scalable, and easy for your colleagues to manage. The manifest is the first thing the platform sees when it loads your component—make sure it tells a clear and accurate story.

Loading...
PrevNext