PCF Components: Package, Deploy & Advanced Features
Get your PCF component from code to production. Learn solution packaging, deployment with the pac CLI, and how to use Device, Utility, and Web API features in your component logic.
From code to production
Think of packaging a PCF component like shipping a product.
You have built the product (TypeScript code). Now you need to package it (wrap it in a solution ZIP), ship it (deploy to Dataverse), and stock it on the shelf (make it available for form designers to use).
Once deployed, your component can also access device features β the camera for barcode scanning, GPS for location tracking, and the Dataverse Web API for reading and writing data directly from the component. These features make PCF components far more powerful than standard controls.
The deployment pipeline
Step 1: Build
npm run build # Compiles TypeScript, bundles resources
Step 2: Quick push (development only)
pac pcf push --publisher-prefix nova # Pushes directly to connected environment
This is fast for development but creates an unmanaged component. Not for production.
Step 3: Solution packaging (production)
# Create a solution project
pac solution init --publisher-name NovaSoft --publisher-prefix nova
# Add your PCF component as a reference
pac solution add-reference --path ../StarRatingComponent
# Build the solution
dotnet build # Creates a managed solution ZIP
# Import to target environment
pac solution import --path bin/Release/NovaSoftComponents.zip
Step 4: Consume
- Model-driven app: Open form designer β select a field β choose your custom control from the control list
- Canvas app: Insert β Get more components β Code β select your component
| Method | pac pcf push | Solution packaging |
|---|---|---|
| Speed | Fast β direct push | Slower β build, package, import |
| Creates | Unmanaged component in dev env | Managed solution for any environment |
| ALM friendly | No β not solution-aware | Yes β travels in solutions, supports versioning |
| Use for | Development and testing | UAT, production, AppSource |
Advanced features: Device, Utility, and Web API
PCF components can access platform features beyond basic rendering:
Device API
// Capture an image from the camera
context.device.captureImage({
allowEdit: false,
height: 300,
width: 300,
preferFrontCamera: false
}).then(
(fileObject) => {
// fileObject.fileContent = base64 image data
// fileObject.fileName, fileObject.fileSize, fileObject.mimeType
this.displayImage(fileObject.fileContent);
}
);
// Get current GPS location
context.device.getCurrentPosition().then(
(position) => {
// position.coords.latitude, position.coords.longitude
this.updateMap(position.coords.latitude, position.coords.longitude);
}
);
| Device Feature | Method | Use Case |
|---|---|---|
| Camera | captureImage() | Photo capture, document scanning |
| Barcode scanner | getBarcodeValue() | Inventory, product lookup |
| GPS | getCurrentPosition() | Location tagging, delivery tracking |
| File picker | pickFile() | File upload from device |
Web API feature
PCF components can perform Dataverse CRUD operations directly:
// Read a record from Dataverse
context.webAPI.retrieveRecord("account", accountId,
"?$select=name,revenue"
).then(
(result) => {
this.updateDisplay(result.name, result.revenue);
}
);
// Create a record
context.webAPI.createRecord("annotation", {
subject: "Photo captured",
"objectid_account@odata.bind": `/accounts(${accountId})`,
documentbody: base64ImageData,
mimetype: "image/png"
});
Utility API
// Open a lookup dialog
context.utils.lookupObjects({
allowMultiSelect: false,
entityTypes: ["account"],
defaultEntityType: "account"
}).then(
(result) => {
// result[0].id, result[0].name, result[0].entityType
}
);
// Get entity metadata
context.utils.getEntityMetadata("contact", ["firstname", "lastname"]).then(
(metadata) => {
// Access field display names, types, etc.
}
);
Scenario: Marcus builds a photo-capture PCF component
Marcus builds a PCF component for field service technicians at a NovaSoft client. When a technician visits a job site:
- The component displays a βCapture Photoβ button
- Tapping it calls
context.device.captureImage()to open the device camera - The photo is saved to a Dataverse Note (annotation) via
context.webAPI.createRecord() - GPS coordinates are captured via
context.device.getCurrentPosition()and stored alongside the photo - The component shows a thumbnail of the captured photo
This component uses three PCF APIs: Device (camera + GPS), WebAPI (save to Dataverse), and standard rendering (thumbnail display). It works in both model-driven and canvas apps.
Marcus deploys a PCF component to the test environment using 'pac pcf push'. It works fine. He then tries to include it in a managed solution for production. The solution build fails with 'component not found'. What went wrong?
π¬ Video coming soon
Next up: The Plug-in Pipeline β how Dataverse processes events, execution stages, and the role of Pre/Post Images.