Configuring Custom Pages
Complete the full lesson to earn 25 points
Work through each section, then tap “Mark as Complete” on the last one.
✦ Skip the page breaks and see fewer ads — read each lesson on a single page with Pro
Configuring Custom Pages in Model-Driven Apps
Welcome to this in-depth lesson on configuring custom pages within Microsoft Power Apps model-driven applications. As you build more sophisticated business solutions, you'll often encounter scenarios where the standard forms, views, and dashboards of a model-driven app don't quite meet the unique user experience or complex functional requirements. This is precisely where custom pages come into play, offering a powerful bridge between the structured world of model-driven apps and the highly flexible, pixel-perfect design capabilities of canvas apps.
This lesson will guide you through understanding, creating, and implementing custom pages, demonstrating how they can significantly enhance the user interface and functionality of your model-driven applications. We'll cover everything from the fundamental concepts to advanced communication patterns, best practices, and common pitfalls, ensuring you have the knowledge to leverage this feature effectively.
1. Introduction: Bridging the Gap with Custom Pages
Model-driven apps are fantastic for rapidly building business applications based on Dataverse data, providing a consistent user experience with forms, views, and dashboards. They excel at data management and process enforcement. However, their strength lies in standardization, which can sometimes be a limitation when you need a highly tailored user interface, intricate data visualizations, or a multi-source data experience that doesn't fit neatly into a record-centric form.
Enter Custom Pages. A custom page is essentially a canvas app embedded within a model-driven app. This means you can design a screen with the full flexibility of the canvas app designer – using custom layouts, rich controls, complex Power Fx logic, and connecting to a wide array of data sources – and then seamlessly integrate it into your model-driven app's navigation, forms, or dialogs. It empowers app makers to deliver bespoke user experiences without completely abandoning the benefits of a model-driven architecture.
Why Custom Pages Matter:
- Enhanced User Experience (UX): Deliver highly customized, intuitive interfaces that go beyond standard model-driven forms. Imagine complex dashboards, guided processes, or unique data entry screens.
- Complex UI/UX Requirements: When standard forms are too restrictive for intricate layouts, multi-step wizards, or dynamic content presentation.
- Canvas App Flexibility within Model-Driven Apps: Leverage the rich control set, advanced Power Fx formulas, and diverse data connectors of canvas apps.
- Multi-Source Data Integration: Display data from Dataverse alongside data from SQL Server, SharePoint, Excel, or custom APIs all on one screen.
- Reduced Development Time: Instead of building custom HTML/JavaScript web resources for complex UI, you can often achieve the desired result faster with Power Fx and canvas app controls.
- Consistency: While offering flexibility, custom pages still inherit some theming from the model-driven app, helping maintain a cohesive look and feel.
In essence, custom pages allow you to pick the best features from both Power Apps worlds, providing a powerful tool for creating truly comprehensive and user-friendly business applications.
2. Understanding the Need for Custom Pages
Before diving into creation, let's solidify why you would choose a custom page over existing model-driven components. Model-driven apps provide a wealth of functionality out-of-the-box, but they are inherently designed around records and data forms.
Limitations of Standard Model-Driven Components:
- Fixed Layouts: Forms and views have predefined section and tab layouts. While configurable, they lack the pixel-perfect control of a canvas app.
- Limited Control Set: The controls available on model-driven forms are primarily for data entry and display related to a single record. Complex charting, interactive maps, or highly custom UI elements are not native.
- Single Data Source Focus (Dataverse): While you can embed subgrids and related records, bringing in truly disparate data sources (e.g., a SQL database, a third-party API, and Dataverse) onto a single, cohesive screen is challenging without custom development.
- Complex Business Logic: While business rules and process flows are powerful, highly interactive, client-side logic that involves dynamic UI changes based on user input across multiple data points is often simpler to implement in Power Fx.
- Branding and Theming: While theming can be applied to model-driven apps, the degree of visual customization for specific screens is limited compared to canvas apps.
Scenarios Where Custom Pages Shine:
Consider these practical examples where custom pages provide superior solutions:
- Guided Onboarding Wizards: A multi-step process for new employees or customers, collecting data across several Dataverse tables and presenting progress visually.
- Executive Dashboards: A custom-designed dashboard pulling aggregated data from Dataverse, an external financial system, and a marketing analytics platform, all presented with interactive charts and KPIs.
- Complex Order Entry Screens: An interface allowing users to select products, configure options, view real-time inventory from an external system, and calculate complex pricing, all before creating an order record in Dataverse.
- Custom Search and Filtering: A highly visual search interface for products or services that allows users to apply multiple filters, view results in a custom gallery, and then navigate to a Dataverse record.
- Interactive Maps: Displaying Dataverse records (e.g., customer locations, service areas) on an interactive map, allowing users to select points and view related details in context.
- Calculators or Quoting Tools: A dedicated screen where users input various parameters, and the app performs complex calculations, displaying instant results and potentially generating a quote record.
Callout: The Power of Context Custom pages aren't just standalone canvas apps; they are context-aware. When embedded in a model-driven app, they can receive information from the host app, such as the current record's ID, the user's context, or other parameters. This seamless communication is what makes them so powerful for extending the model-driven experience, rather than just linking to a separate app.
3. Anatomy of a Custom Page
A custom page, at its core, is a specialized type of canvas app. However, it operates within the confines and context of a model-driven app, leading to some unique characteristics.
Key Characteristics:
- It's a Canvas App: All your knowledge of canvas app design, controls, and Power Fx applies directly to custom pages. You design them using the same Power Apps Studio.
- It Lives within a Solution: Custom pages must be created and managed within a Power Apps solution. This is crucial for application lifecycle management (ALM) and deployment.
- Host Object for Communication: This is the most critical distinction. A custom page has access to a
Hostobject, which facilitates interaction with the parent model-driven app. This object allows you to:- Retrieve parameters passed from the model-driven app (
Host.Param). - Navigate within the model-driven app (
Host.NavigateTo). - Close the custom page (
Host.Back). - Refresh the host form/view (
Host.RefreshHost).
- Retrieve parameters passed from the model-driven app (
- No Standalone Play: Custom pages cannot be played directly as standalone canvas apps. They are designed exclusively to function within a model-driven app.
- Inherited Theming: Custom pages often pick up some of the theming from the model-driven app, helping them blend in visually.
Understanding the Host Object
The Host object is your gateway to interacting with the model-driven app context. Let's look at its key properties and methods:
Host.Param("ParameterName"): Retrieves a specific parameter passed to the custom page from the model-driven app. For example, if you open a custom page from a form and pass the current record's GUID asrecordId, you'd access it usingHost.Param("recordId").Host.Back(OptionalDataToReturn): Closes the custom page. If the page was opened as a dialog,OptionalDataToReturncan be used to pass data back to the calling model-driven component.Host.RefreshHost(): Refreshes the underlying model-driven form or view that opened the custom page. This is incredibly useful after a user performs an action in the custom page that updates data displayed on the host form.Host.NavigateTo(Target, Parameters, Transition): Allows you to navigate to another page, form, view, or even another custom page within the same model-driven app.Target: The name of the sitemap area, table, or custom page to navigate to.Parameters: A record of parameters to pass to the target.Transition: Visual transition (e.g.,Transition.None,Transition.Cover).
Host.Context: Provides information about the model-driven app context, such as the current app ID, current user, etc. (Less commonly used thanHost.ParamorHost.NavigateTo).
4. Creating Your First Custom Page (Step-by-Step)
Let's walk through the process of creating a simple custom page and integrating it into a model-driven app. For this example, we'll create a custom page that allows a user to quickly update a specific field on an Account record and then return to the Account form.
Prerequisites:
- Access to a Power Apps environment.
- A model-driven app to integrate the custom page into (or create a new one).
- A Dataverse table (e.g.,
Accounttable) with some sample data.
Step 1: Create a New Solution
It's a best practice to always work within solutions for ALM purposes.
- Navigate to make.powerapps.com.
- Select your environment from the top right.
- In the left navigation pane, click Solutions.
- Click New solution.
- Provide a Display name (e.g., "Custom Page Demo Solution").
- Choose a Publisher (create a new one if you don't have a suitable one).
- Click Create.
Step 2: Add a New Custom Page to the Solution
Now, let's create the custom page itself.
- Open your newly created solution.
- Click New > Page > Custom page (preview).
- Give your custom page a Name (e.g., "AccountQuickUpdatePage").
- Click Create.
This will launch the Power Apps Studio with a blank canvas app, specifically configured as a custom page. Notice the default screen size and the Host object available.
Step 3: Design the Custom Page
For our example, we want to display the account name and allow updating a "Description" field.
Change Screen Size (Optional but Recommended): Custom pages often function better with a flexible width.
- Select the screen in the tree view.
- In the Properties pane on the right, under "Size," select a template like "Tablet" or "Phone" if you want a fixed size, or use custom dimensions. For a dialog, a smaller, fixed size is often appropriate. Let's set
Widthto700andHeightto400for a simple dialog.
Add a Label for the Account Name:
- Insert a Text label control.
- Set its
Textproperty to"Account Name: " & Host.Param("accountName"). (We'll passaccountNamefrom the model-driven app later). - Adjust font size and position.
Add a Text Input for Description:
- Insert a Text input control.
- Rename it to
txtDescription. - Set its
Modeproperty toMultiline. - Set its
Defaultproperty toHost.Param("accountDescription"). (We'll passaccountDescriptionlater). - Adjust its width and height to allow for more text.
Add a Button to Save Changes:
- Insert a Button control.
- Set its
Textproperty to"Save and Close". - Rename it to
btnSave. - Set its
OnSelectproperty to the following Power Fx:
// Update the Account record in Dataverse Patch( Accounts, LookUp(Accounts, Account = GUID(Host.Param("accountId"))), { Description: txtDescription.Text } ); // Refresh the host form to show the updated description Host.RefreshHost(); // Close the custom page Host.Back();- Explanation:
Patch(Accounts, ...): This is the core function to update a Dataverse record.Accountsis the table we're targeting.LookUp(Accounts, Account = GUID(Host.Param("accountId"))): This finds the specific Account record to update.Host.Param("accountId")will provide the GUID of the current account from the model-driven form. We useGUID()to convert the text parameter into a GUID type.{ Description: txtDescription.Text }: This specifies the field to update (Description) and its new value (from ourtxtDescriptioninput).Host.RefreshHost(): After saving, this tells the model-driven app to refresh the form that opened this custom page. This ensures the user sees the updated description immediately.Host.Back(): This closes the custom page, returning the user to the previous screen in the model-driven app.
Add a Button to Cancel:
- Insert another Button control.
- Set its
Textproperty to"Cancel". - Rename it to
btnCancel. - Set its
OnSelectproperty toHost.Back();. This simply closes the page without saving.
Step 4: Integrate the Custom Page into a Model-Driven App
Now that our custom page is designed, we need to make it accessible within our model-driven app. We'll add it as a dialog launched from a button on the Account form.
- Add the Account Table to Your Solution:
- In your solution, click Add existing > Table.
- Select
Accountand click Next. - Choose Select objects and select the
Main Form(or any form you want to add the button to). - Click Add.
- Add the Custom Page to the Model-Driven App:
- In your solution, find your model-driven app (or create a new one).
- Open the model-driven app in the App Designer.
- Click Pages > Add page.
- Select Custom page and choose "AccountQuickUpdatePage".
- Click Add. (This adds it as a component, but we won't use it directly from the sitemap for this example).
- Add a Command Button to the Account Main Form:
In your solution, navigate to Tables > Account > Forms.
Open the "Main" form for the Account table.
At the top, click ... (More commands) > Edit command bar.
Select the Main form command bar and click Edit. This opens the modern command designer.
Click + New command.
Set Label to "Quick Update Description".
Set Icon to a suitable icon (e.g.,
Edit).For Action, select Run Power Fx.
In the formula bar, enter the following Power Fx:
// Open the custom page as a dialog, passing parameters Navigate( { PageName: "AccountQuickUpdatePage", // The name of your custom page PageType: "Custom", // Parameters to pass to the custom page Data: { accountId: Self.Selected.Item.Account, // Current record's GUID accountName: Self.Selected.Item.'Account Name', // Current record's Name accountDescription: Self.Selected.Item.Description // Current record's Description } }, NavigateTarget.Dialog // Open as a dialog )Explanation:
Navigate(...): This function is used in the model-driven command bar to open different pages.PageName: "AccountQuickUpdatePage": Specifies the custom page to open.PageType: "Custom": Indicates it's a custom page.Data: {...}: This is where you define the parameters to pass.accountId: We're passing the GUID of the current record usingSelf.Selected.Item.Account.accountName: The name of the account.accountDescription: The current description.- Important: The names (
accountId,accountName,accountDescription) must exactly match what you use inHost.Param()within the custom page.
NavigateTarget.Dialog: This opens the custom page as a modal dialog, which is ideal for quick update scenarios. You could also useNavigateTarget.NewWindoworNavigateTarget.CurrentTabif you wanted it to replace the current form.
Choose where to display the command (e.g., "Main form" or "Subgrid").
Click Save and Publish.
Step 5: Test Your Custom Page
- Open your model-driven app.
- Navigate to the Accounts table and open an existing account record.
- You should see your "Quick Update Description" button in the command bar.
- Click the button. Your custom page should open as a dialog, displaying the account name and its current description.
- Modify the description, then click "Save and Close."
- The dialog should close, and the Account form should refresh, showing your updated description.
This hands-on example demonstrates the fundamental flow: creating the custom page, designing its UI and logic (including Power Fx to interact with Dataverse and the host app), and then integrating it into your model-driven app's command bar to pass context and receive feedback.
5. Data Interaction and Communication
The ability for a custom page to communicate bidirectionally with its host model-driven app is what makes it so powerful. Let's delve deeper into parameter passing and data return mechanisms.
Passing Parameters to a Custom Page
When you open a custom page, you often need to provide it with context from the model-driven app. This is done by passing parameters.
From Sitemap: When adding a custom page to the sitemap, you can define parameters in the "Parameters" field. These are static key-value pairs.
From Command Bar (Power Fx
Navigate): This is the most common and dynamic method. As shown in the example above, theDataproperty of theNavigatefunction is a record that holds your parameters.// Example from a command button on an Account form Navigate( { PageName: "MyCustomPage", PageType: "Custom", Data: { recordId: Self.Selected.Item.Account, // Pass the current record's GUID recordType: "account", // Pass the entity logical name someSetting: "true" // Pass a custom setting } }, NavigateTarget.Dialog )From JavaScript Web Resource: If you're opening a custom page from JavaScript (e.g., from a form script), you use
Xrm.Navigation.navigateTowith thepageTypeset tocustomand pass parameters in thedataproperty.// Example from a JavaScript web resource on a form var pageInput = { pageType: "custom", name: "MyCustomPage", // Logical name of the custom page data: { recordId: Xrm.Utility.getPageContext().input.entityId, recordType: Xrm.Utility.getPageContext().input.entityTypeName } }; Xrm.Navigation.navigateTo(pageInput);
Retrieving Parameters in the Custom Page (Host.Param())
Inside your custom page, you access these passed parameters using Host.Param("ParameterName").
// On the custom page, to get the record ID
Set(varRecordId, GUID(Host.Param("recordId")));
// To display the record type
"Current Entity: " & Host.Param("recordType")
// To use a boolean setting
If(Host.Param("someSetting") = "true", Notify("Setting is true!"), Notify("Setting is false!"))
Note:
Host.Param()always returns a text string. If you expect a GUID, number, or boolean, you'll need to use conversion functions likeGUID(),Value(), orBoolean()respectively.
Returning Data from a Custom Page
While custom pages are primarily for input and interaction, you might need to signal back to the host app or pass a simple result.
Host.Back(OptionalDataToReturn):- This closes the custom page.
- If the custom page was opened as a dialog, you can pass a record of data back to the calling model-driven component. The
Navigatefunction in the command bar (orXrm.Navigation.navigateToin JS) can optionally have acallbackfunction to process this returned data. - Example (Custom Page
OnSelectof a "Select" button):Host.Back({SelectedValue: Gallery1.Selected.ID, Message: "Item selected successfully"}); - Example (Model-Driven Command Bar
Navigatewith Callback):// This is a more advanced scenario and often involves JavaScript // For Power Fx command bar, `Navigate` doesn't directly support a callback for returned data in this way. // Instead, `Host.RefreshHost()` is the primary way to signal changes. // If you need to "return" data to Power Fx, consider writing the data to a temporary Dataverse record // or using Host.RefreshHost() to trigger a refresh that reads updated data.
Host.RefreshHost():- This is the most common and effective way to signal that data has changed and the host form/view should reflect those changes. It doesn't pass specific data back, but it triggers a refresh of the underlying model-driven component. This is often sufficient when the custom page is modifying data that the host form is already displaying.
Host.NavigateTo(Target, Parameters, Transition):- This allows you to close the custom page and then navigate the model-driven app to a completely different page, form, or view. This is useful for complex workflows where the custom page is a step, and the next step is a different part of the model-driven app.
- Example: After completing a complex setup in the custom page, navigate to the related record's main form.
Host.NavigateTo( { PageType: "entityrecord", EntityName: "account", EntityId: GUID(Host.Param("accountId")) }, Transition.Cover );
Interacting with Dataverse within the Custom Page
Since a custom page is a canvas app, you connect to Dataverse (and other data sources) just like any other canvas app.
Add Dataverse tables: In the Power Apps Studio for your custom page, go to Data > Add data > Dataverse. Select the tables you need (e.g.,
Accounts,Contacts,Opportunities).Perform CRUD operations:
- Read: Use
LookUp(),Filter(),Search(),Sort()with galleries and forms to display data. - Create: Use
Patch()orSubmitForm()with an Edit form. - Update: Use
Patch()orSubmitForm()with an Edit form. - Delete: Use
Remove()orRemoveIf().
// Example: Create a new contact from the custom page Patch( Contacts, Defaults(Contacts), { 'First Name': txtFirstName.Text, 'Last Name': txtLastName.Text, 'Email': txtEmail.Text, 'Company Name (Accounts)': LookUp(Accounts, Account = GUID(Host.Param("accountId"))) // Link to the host account } ); Notify("Contact created successfully!"); Host.RefreshHost(); Host.Back();- Read: Use
6. Advanced Custom Page Scenarios
Custom pages offer a lot of room for advanced implementations.
Responsive Design
One of the biggest advantages of custom pages is the ability to create responsive layouts, which is challenging with standard model-driven forms.
- Fluid Layouts: Instead of fixed widths, use formulas like
Parent.WidthandParent.Heightfor control dimensions to make them scale with the screen. - Containers: Use horizontal and vertical containers (from the "Layout" tab in the Insert pane) to manage the flow and alignment of controls. These containers are crucial for building truly responsive interfaces.
App.WidthandApp.Height: Use these global properties to adjust layouts based on the overall screen size or orientation. For example, you might have different layouts forApp.Width < 600(phone portrait) vs.App.Width >= 600(tablet/desktop).Self.Width/Self.Height: Refer to the control's own width/height.XandYProperties: For positioning, instead of hardcoded numbers, use formulas like(Parent.Width - Self.Width) / 2to center a control horizontally.
Integrating with JavaScript/TypeScript (Web Resources)
While Power Fx covers most logic, sometimes you need to interact with client-side model-driven app features not exposed via Host object, or leverage existing JavaScript libraries.
- Calling JavaScript from Power Fx:
- This is generally not directly supported in custom pages in the same way it is for canvas apps embedded in model-driven forms (using
Parent.Xrm.Utility.getResource). - However, you can use
Host.NavigateToto open another model-driven page (like a form) and pass parameters. That form could have a JavaScript web resource that runs on load and responds to those parameters. This is an indirect method. - A more direct approach involves having a JavaScript web resource on the host model-driven form. The custom page then uses
Host.RefreshHost()orHost.Back()to trigger an event on the host form, and the JavaScript on the host form can then react to that event.
- This is generally not directly supported in custom pages in the same way it is for canvas apps embedded in model-driven forms (using
- Calling Power Fx from JavaScript:
- This is not directly supported. JavaScript on the model-driven form cannot directly call functions within the custom page.
- Again, the typical pattern is for the JavaScript to manipulate data in Dataverse, and the custom page (or the host form itself) then reacts to those data changes.
Callout: Power Fx vs. JavaScript for Custom Pages
Feature Power Fx in Custom Page JavaScript in Model-Driven App Host Primary Use UI logic, data manipulation, canvas app features. Model-driven form/view manipulation, advanced client-side integration, complex validations. Data Access Direct access to Dataverse and 100s of connectors. Direct access to Dataverse via Web API (Xrm.WebApi), limited connector access. UI Control Full control over custom page UI elements. Limited control over standard model-driven forms, can inject custom HTML/JS web resources. Communication Hostobject for MD-app interaction.Xrmobject for MD-app interaction.Complexity Generally faster for UI logic, lower learning curve. Higher learning curve, more powerful for deep MD-app customization. Best For Custom UI, multi-source data, guided processes, complex visualizations. Form events, ribbon button actions, deep integration with MD-app APIs. Choose Power Fx for most custom page logic. Reserve JavaScript for scenarios where you need to interact deeply with the model-driven app's object model (e.g., specific form controls, business process flows, external library integration) that Power Fx cannot directly address.
Using Custom Connectors
Custom pages can leverage custom connectors, just like any other canvas app. This allows you to integrate with virtually any RESTful API, bringing external data and services directly into your model-driven app experience.
- Create your Custom Connector: Define the API endpoints, authentication, and request/response structures.
- Add to Custom Page: In the Power Apps Studio for your custom page, add the custom connector as a data source.
- Use in Power Fx: Call the custom connector's actions and functions within your Power Fx formulas to send and receive data.
Security Considerations
- Sharing the Custom Page: The custom page, being a canvas app, must be shared with the users who will access the model-driven app. If it's not shared, users will see an error message. Share it with "User" permissions.
- Data Source Permissions: Ensure users have the necessary Dataverse security roles and permissions to access the underlying Dataverse tables and records used by the custom page. If the custom page connects to other data sources (e.g., SQL, SharePoint), users also need permissions to those sources.
- Environment Variables: For connection references or values that change between environments (Dev, Test, Prod), use environment variables within your custom page.
7. Best Practices for Custom Pages
To ensure your custom pages are performant, maintainable, and provide a great user experience, follow these best practices.
Performance
- Minimize Data Calls: Fetch only the data you need. Use
Filter(),LookUp(), andSelect()to reduce the amount of data transferred. Avoid making repeated, identical data calls. - Optimize Power Fx Formulas: Complex formulas can impact performance. Break them down, use
With()for intermediate calculations, and avoid delegable warnings. - Lazy Loading: For complex pages with many controls or data sources, consider loading less critical data only when it's needed (e.g., on a tab selection, or when a user scrolls).
- Avoid
ClearCollect()onOnStart:ClearCollect()can be slow. UseCollect()orClear()in conjunction withCollect()on specific events rather thanOnStartif possible. - Componentization: If you have reusable elements, create canvas components. This reduces redundancy and makes your app more efficient.
User Experience (UX)
- Consistency with Model-Driven App Theme: While custom pages offer flexibility, try to align with the model-driven app's overall look and feel (fonts, colors, spacing) to create a cohesive experience.
- Clear Navigation: Ensure users understand how to navigate within the custom page and how to return to the model-driven app. Use clear button labels (e.g., "Save," "Cancel," "Next," "Back").
- Accessibility: Design with accessibility in mind. Use appropriate control types, provide meaningful labels, and ensure keyboard navigation works.
- Error Handling and User Feedback: Implement
Notify()functions for success, warning, and error messages. Provide clear feedback when operations are in progress (e.g., using a loading spinner). - Responsive Design: Plan your layout for different screen sizes if users will access the model-driven app on various devices. Utilize containers and flexible sizing.
Maintainability
- Work in Solutions: Always create and manage custom pages within solutions. This is non-negotiable for ALM.
- Clear Naming Conventions: Use consistent and descriptive names for your controls, variables, and collections (e.g.,
lblAccountName,txtDescription,btnSave,varSelectedRecord,colItems). - Comments: Add comments to complex Power Fx formulas to explain their purpose.
- Modular Design: Break down complex logic into smaller, manageable pieces (e.g., using named formulas, reusable components).
- Environment Variables: For connection references, URLs, or other values that vary between environments, use environment variables. This simplifies deployment and configuration.
8. Common Pitfalls and How to Avoid Them
Even with the best intentions, developers can run into issues with custom pages. Awareness is key to avoiding these common pitfalls.
- Incorrect Parameter Passing:
- Mistake: Mismatched parameter names between the
Navigatefunction in the command bar andHost.Param()in the custom page. Incorrect data types (e.g., passing a string when a GUID is expected without conversion). - Avoid: Double-check parameter names for exact matches (case-sensitive). Always use
GUID(),Value(),Boolean()to convertHost.Param()outputs to the correct data type in the custom page.
- Mistake: Mismatched parameter names between the
- Security Issues (Page Not Loading):
- Mistake: Forgetting to share the custom page (canvas app) with the relevant users or security groups.
- Avoid: After creating and saving the custom page, ensure it is shared with "User" permissions to everyone who needs access to the model-driven app. Also, verify Dataverse security roles for underlying data.
- Performance Bottlenecks:
- Mistake: Making too many non-delegable data calls, complex formulas in
OnStart, or fetching large datasets unnecessarily. - Avoid: Follow performance best practices (minimize data calls, optimize Power Fx, use delegation). Test performance with realistic data volumes.
- Mistake: Making too many non-delegable data calls, complex formulas in
- UI/UX Inconsistency:
- Mistake: Designing a custom page that looks completely different from the rest of the model-driven app, leading to a jarring user experience.
- Avoid: Try to match fonts, colors, and general layout principles of the model-driven app. Use consistent branding elements.
- Over-reliance on Custom Pages:
- Mistake: Using a custom page for functionality that could be easily achieved with a standard model-driven form, business rule, or simple JavaScript. This adds unnecessary complexity.
- Avoid: Evaluate whether a custom page is truly necessary. If a standard form with a few custom controls or business rules can do the job, stick with that. Custom pages are for extended functionality, not basic data entry.
- Testing Challenges:
- Mistake: Not thoroughly testing the custom page in different scenarios, with different user roles, and on various devices.
- Avoid: Test the custom page flow end-to-end. Verify parameter passing, data updates, error handling, and responsiveness. Test with users who have different security roles to ensure they have the correct permissions.
9. Quick Reference: Custom Page Integration Points
Custom pages offer flexibility in how they are presented within your model-driven app. Here's a quick comparison of the main integration points:
| Integration Point | Description | Use Cases | Pros | Cons |
|---|---|---|---|---|
| Sitemap | Appears as an item in the left navigation pane. | Standalone dashboards, full-screen wizards, custom reporting interfaces. | Full screen real estate, dedicated experience. | Can feel disconnected from specific records. |
| Dialog | Opens as a modal pop-up window over the current screen. | Quick edits, confirmation dialogs, multi-step forms directly related to a record. | Focused user interaction, keeps context of parent page. | Limited screen space, can be intrusive if overused. |
| Form Tab | Embedded directly into a tab on a model-driven form. | Displaying related information, custom visualizations tied to a record, interactive sub-forms. | Seamless integration with record data, always visible. | Fixed size constraints, can slow down form load if complex. |
| Command Bar | Launched from a button on a form or view command bar. | Contextual actions on a selected record, initiating workflows, opening related custom pages. | Highly contextual, easy to find for relevant actions. | Requires Power Fx or JavaScript for dynamic parameter passing. |
10. Common Questions (FAQ)
Here are some frequently asked questions about custom pages:
Can I use a custom page offline? Yes, if the custom page is designed to work offline (e.g., using the
Offlinecapability of Dataverse tables), it will generally function within the model-driven app's offline capabilities. However, you must explicitly enable offline for the model-driven app and ensure the custom page's data sources are configured for offline use.How do I debug a custom page? You debug a custom page just like any other canvas app. Open the custom page in Power Apps Studio (from your solution). Use the
Monitortool to trace data flows and formula execution. You can also useNotify()messages to display variable values during runtime.Can I embed a custom page within another custom page? No, you cannot directly embed one custom page inside another. However, you can use canvas app components within a custom page to achieve modularity and reuse UI elements and logic. You can also use
Host.NavigateToto move from one custom page to another.What are the licensing implications for custom pages? Custom pages are a feature of Power Apps and require appropriate Power Apps licenses for users. If your custom page connects to premium connectors (e.g., SQL Server, custom connectors), users will need a Power Apps Per App or Per User license. Standard Dataverse access is covered by typical Dynamics 365 or Power Apps licenses.
Can a custom page be created outside of a solution? Technically, you can create a canvas app and then convert it to a custom page. However, for proper ALM and to ensure it functions correctly within a model-driven app, you must create and manage custom pages within a solution.
11. Key Takeaways
Custom pages are a game-changer for extending the capabilities and user experience of model-driven apps. By understanding and applying the concepts covered in this lesson, you can build truly powerful and flexible business applications.
Here are the key takeaways:
- Custom Pages are Canvas Apps in a Model-Driven Context: They combine the structured data management of model-driven apps with the flexible UI/UX and diverse data connectivity of canvas apps.
- The
HostObject is Your Gateway: This object (Host.Param,Host.Back,Host.RefreshHost,Host.NavigateTo) is crucial for communication between the custom page and its parent model-driven app. - Parameter Passing is Essential: Use the
Dataproperty in theNavigatefunction (from command bar Power Fx or JavaScript) to pass contextual information (like record IDs) to your custom page. Remember to convertHost.Param()outputs to the correct data types. - Integrate Thoughtfully: Choose the right integration point (sitemap, dialog, form tab, command bar) based on the custom page's purpose and how it fits into the user's workflow. Dialogs are excellent for focused, contextual interactions.
- Prioritize Performance and UX: Optimize data calls, use responsive design techniques, and ensure a consistent look and feel with the rest of your model-driven app. Provide clear user feedback.
- Always Work in Solutions: For robust application lifecycle management, all custom pages must be created and managed within Power Apps solutions.
- Know When to Use Them: Custom pages are best for complex UI, multi-source data, guided processes, or highly interactive experiences that standard model-driven components cannot easily deliver. Avoid using them for simple tasks that existing components can handle.
By mastering custom pages, you gain a powerful tool to create truly compelling and comprehensive business applications that meet even the most demanding user requirements.
Enjoying the courses?
Everything stays free. Pro shows fewer ads, doubles your daily points limit so you progress twice as fast, and lets you read each lesson on one page.
- ✓ Fewer advertisements
- ✓ 2× daily points limit
- ✓ Distraction-free lessons