Canvas Developer Guide
Version 61.0, Summer 24
Last updated: July 5, 2024
©
Copyright 20002024 Salesforce, Inc. All rights reserved. Salesforce is a registered trademark of Salesforce, Inc., as are other
names and marks. Other marks appearing herein may be trademarks of their respective owners.
CONTENTS
GETTING STARTED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chapter 1: Introducing Canvas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Canvas Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Where Canvas Apps Appear . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Supported Browsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Supported Salesforce Editions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
User Permissions Required . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
User Interface Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Canvas App Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Canvas Personal Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Canvas Personal App Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Enabling Canvas Personal Apps within an Organization . . . . . . . . . . . . . . . . . . . . . . . . 9
Making an App a Canvas Personal App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Uninstalling a Canvas Personal App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Chapter 2: Quick Start (currently unavailable) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Create the App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Set the App Location . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Chapter 3: Quick StartAdvanced . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Clone the Project from GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Run the Web App Locally . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Create the Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Configure Who Can Access the Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Deploy the Web App to Heroku . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Update the Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Package the Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Upload the Canvas App Package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Install the Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Configure Who Can Access the Installed Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
USING CANVAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Chapter 4: Canvas SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Referencing the Canvas SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Signed Request Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
OAuth 2.0 Authorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
SAML Single Sign-On for Canvas Apps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Getting Context in Your Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Cross-Domain XHR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Getting a List of Chatter Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Posting to a Chatter Feed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Alternatives to Cookies for User Tracking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Resizing a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Automatically Resizing a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Explicitly Resizing a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Getting the Size of a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Subscribing to Parent Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Handling Orientation Changes in Your Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Implementing Canvas App Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Canvas App Events Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Creating a Canvas App Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Subscribing to a Canvas App Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Unsubscribing from a Canvas App Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Using Streaming API in a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Using the Streaming API Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Subscribing to a Streaming API Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Unsubscribing from a Streaming API Event . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Debugging in a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Using the <select> Tag in a Canvas App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Chapter 5: Canvas Apps and Visualforce Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Visualforce Page Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Visualforce Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
apex:canvasApp Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Returning Fields in the Record Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Using Events between a Visualforce Page and a Canvas App . . . . . . . . . . . . . . . . . . . . . . . 60
Publishing a Canvas Event from a Visualforce Page . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Resizing a Canvas App in a Visualforce Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Subscribing to Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Unsubscribing from Events in a Visualforce Page . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Chapter 6: Lightning Component Code Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Chapter 7: Canvas Apps in a Page Layout or a Mobile Card . . . . . . . . . . . . . . . . . . . 66
Where Canvas Apps Appear in a Page Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Add a Canvas App to a Page Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Chapter 8: Canvas Apps in the Publisher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Set Canvas App Location and Create the Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Create the Action Manually . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Contents
Canvas SDK Publisher Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Publisher Context Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Publisher Canvas App Access Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Chapter 9: Canvas Apps in the Chatter Feed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Chatter Feed Context Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Chatter Feed Canvas App Access Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Chapter 10: Canvas in the Salesforce Mobile App . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Set Canvas App Location and Add it to the Navigation Menu . . . . . . . . . . . . . . . . . . . . . . . . 78
Salesforce Mobile App Context Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Salesforce Mobile App Access Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Salesforce Mobile App Custom Icons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Salesforce Mobile App Navigation Methods for Use with Canvas Apps . . . . . . . . . . . . . . . . . 80
Chapter 11: Customizing Your App Lifecycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Creating a CanvasLifecycleHandler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Associating Your CanvasLifecycleHandler with Your App . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Filtering CanvasRequest Context Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Controlling Canvas App Behavior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Presenting User Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Testing Your CanvasLifecycleHandler Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Distributing Your CanvasLifecycleHandler Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
REFERENCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Chapter 12: Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
CanvasRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
SignedRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
Chapter 13: Canvas Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
Contents
GETTING STARTED
CHAPTER 1 Introducing Canvas
Canvas enables you to easily integrate a third-party application in Salesforce. Canvas is a set of tools and
JavaScript APIs that you can use to expose an application as a Canvas app. Then take your new or existing
applications and make them available to your users as part of their Salesforce experience.
In this chapter ...
Canvas Scenarios
Where Canvas Apps
Appear
Important: To prepare your Canvas apps for the new web browser restrictions on third-party
cookies, see How Third-Party Cookie Restrictions Impact Salesforce Canvas Apps in Salesforce Help.
Supported Browsers
Instead of redesigning and reintegrating your external applications, you can now use these tools to
integrate your technology within Canvas. Canvas includes tools that handle:
Supported Salesforce
Editions
AuthenticationIf your application requires authorization, you can implement it by using a signed
request or OAuth 2.0.
User Permissions
Required
ContextAPI support that enables you to retrieve context information about the environment in
which the canvas app is running.
User Interface
Considerations
Canvas App Process
Cross-domain XHRJavaScript support for cross-domain XML HTTP requests back to the Salesforce
domain.
Canvas Personal
Apps
ResizingMethods that support the ability to resize your canvas app.
EventsEvents provide a JavaScript-based way to send and receive events between canvas apps.
Use events to enable communication between multiple canvas apps on a single page.
Canvas Apps in AuraAn Aura component that lets you expose your canvas app in a custom Aura
component.
Canvas Apps in VisualforceA Visualforce component that lets you expose your canvas app on a
Visualforce page.
Canvas Apps in the PublisherLets you add a canvas app as a custom action and expand the
publisher to include a canvas app.
Canvas Apps in the Chatter FeedLets you expose your canvas apps as feed items.
Canvas in the Salesforce Mobile AppMakes your canvas apps available in the Salesforce mobile
app.
The third-party app that you want to expose as a Canvas app can be written in any language. The only
requirement is that the app has a secure URL (HTTPS).
Other Integration Options
Before diving into Canvas, consider these other options for integrating a third-party application in
Salesforce:
Web tabs
Canvas apps present third-party applications as part of a page. Web tabs can present a full application
in a large screen space.
1
HTML iframes in a custom component
Canvas apps provide greater functionality than developing with iframes. Iframes are sometimes
easier to integrate with your application.
SEE ALSO:
Canvas Scenarios
Canvas App Process
Quick Start (currently unavailable)
2
Introducing Canvas
Canvas Scenarios
From a high-level view, there are two common scenarios where Canvas is implemented.
Application integrationYoure a partner, systems integrator, or customer that builds cloud apps, and youd like to integrate these
applications with Salesforce.
Application rationalization/enterprise desktopYoure a large organization that has many existing apps that your users access in
addition to Salesforce. Youd like to integrate these apps into Salesforce so that users can accomplish all of their tasks in one place.
SEE ALSO:
Introducing Canvas
Where Canvas Apps Appear
Where Canvas Apps Appear
Canvas apps can appear in a few places.
In the Canvas App Previewer in the organization in which it was created
In the Chatter feed, if you code the canvas app to appear there and the current user has access to the canvas app
On the Chatter tab, in the Chatter apps list, for any user who has been allowed access to it
As an option in the navigation menu in the Salesforce mobile app, for any user who has been allowed access to it
In an Open CTI call control tool after you add it to the call centers definition file
In the Chatter publisher and Salesforce mobile app action bar, if you configure it to appear as a quick action
In a Salesforce Console after you add it as a custom console component
In a Visualforce page after you add it to a page and make that page available to users
In a Profile page in the Chatter apps list, for any user who has been allowed access to it
In a page layout for a standard or custom object after you add the canvas app to the page layout. Depending on where you place
the canvas app on the page layout, the canvas app can appear in the record detail page or in a mobile card.
Where an installed canvas app appears depends on the values you select in the Locations field when creating the connected app
in Salesforce.
Chatter FeedThe canvas app appears in the feed. If this option is selected, you must create a CanvasPost feed item and ensure
that the current user has access to the canvas app.
Chatter TabThe canvas app appears in the app navigation list on the Chatter tab. If this option is selected, the canvas app appears
there automatically.
ConsoleThe canvas app appears in the footer or sidebars of a Salesforce console. If this option is selected, you must choose where
the canvas app appears in a console by adding it as a custom console component.
Layouts and Mobile CardsThe canvas app can appear on a page layout or a mobile card. If this option is selected, you choose
where the canvas app appears by adding it to the page layout.
Mobile NavThe canvas app is accessible from the mobile app navigation menu.
Open CTIThe canvas app appears in the call control tool. If this option is selected, you must specify the canvas app in your call
centers definition file for it to appear.
PublisherThe canvas app appears in the Chatter publisher and action bar. If this option is selected, you must also create a canvas
custom action and add it to the global publisher layout or to an objects page layout.
3
Canvas ScenariosIntroducing Canvas
Visualforce PageThe canvas app can appear on a Visualforce page . If you add an <apex:canvasApp> component to
expose a canvas app on a Visualforce page, be sure to select this location for the canvas app; otherwise, youll receive an error.
SEE ALSO:
Introducing Canvas
Set the App Location
Supported Browsers
Supported Browsers
Learn where Canvas is supported.
Important: To prepare your Canvas apps for the new web browser restrictions on third-party cookies, see How Third-Party Cookie
Restrictions Impact Salesforce Canvas Apps in Salesforce Help.
Canvas supports the most recent versions of the following browsers:
Mozilla
®
Firefox
®
(preferred)
Google Chrome
Microsoft
®
Internet Explorer
®
(be sure Compatibility Mode is disabled)
Microsoft
®
Edge
Apple
®
Safari
®
(be sure to set the Block Cookies setting to Never)
See the supported browsers topics in Salesforce Help for specific versions and some important considerations. Because Canvas is not
built on Lightning, it still supports Microsoft
®
Internet Explorer
®
11.
If your app uses session cookies, you might need to set your P3P header to allow for third-party cookies or change the browser settings
to allow all session cookies.
SEE ALSO:
Supported Browsers
Introducing Canvas
Supported Salesforce Editions
Alternatives to Cookies for User Tracking
Supported Salesforce Editions
Canvas supports these Salesforce Editions:
Install a canvas appPublish a canvas appCreate a canvas appEdition
Yes*NoYes*Group
Yes*NoYes*Professional
YesNoYesEnterprise
YesNoYesUnlimited
4
Supported BrowsersIntroducing Canvas
Install a canvas appPublish a canvas appCreate a canvas appEdition
YesNoYesPerformance
YesYesYesDeveloper
*Group and Professional Editions can only use or create canvas apps that have a permitted users value of Admin approved users are
pre-authorized if profiles and page layouts are enabled in the org.
SEE ALSO:
Introducing Canvas
User Permissions Required
User Permissions Required
You need certain user permissions to interact with canvas apps.
The following user permissions are required to create canvas apps and view them in the Canvas App Previewer.
Customize Application
Modify All Data
Note: The "Customize Application" user permission is required to see Canvas apps in the App Launcher on mobile.
SEE ALSO:
Introducing Canvas
Configure Who Can Access the Canvas App
Configure Who Can Access the Installed Canvas App
User Interface Considerations
Canvas Size
The frame size for canvas apps varies depending on the location where the app appears. When using the SDK, these values are returned
in the Dimensions object.
Note: If you plan to use your canvas app in the Salesforce mobile app, take into account mobile device screen sizes. For more
information, see Canvas in the Salesforce Mobile App.
DescriptionLocation
The default dimensions are 800 pixels (wide) by 900 pixels (high). The
maximum dimensions are 1,000 pixels (wide) by 2,000 pixels (high).
Chatter tab
The default dimensions are 420 pixels (wide) by 100 pixels (high). The
maximum dimensions are 420 pixels (wide) by 400 pixels (high).
Chatter feed
5
User Permissions RequiredIntroducing Canvas
DescriptionLocation
The default and maximum dimensions are determined by the way you
set up the custom console component.
Open CTI
The way you set up the canvas publisher action determines the default
height. The default width is 522 pixels. The maximum dimensions are
522 pixels (wide) by 500 pixels (high).
Publisher
The default and maximum dimensions are determined by the way you
set up the custom console component.
Salesforce Console
The default dimensions are 800 pixels (wide) by 900 pixels (high). A
developer can change these dimensions by modifying the attributes on
the apex:canvasApp Component.
Visualforce page
Logo Image
The logo image associated with a canvas app is displayed when someone installs your canvas app or during OAuth authentication when
the user is prompted to allow the app to run. We recommend that you use an image of size 256 pixels (high) by 256 pixels (wide).
Icon Image
The icon image associated with a canvas app is displayed in these locations.
To the left of the link to your canvas app on the Chatter tab, in the Chatter apps list
To the left of the link to your canvas app in the Canvas App Previewer
In the Salesforce navigation menu
We recommend that you use an image of size 60 pixels (wide) by 60 pixels (high) so that the icon appears correctly in both mobile and
the Salesforce site. If you have no plans to display your icon in the Salesforce mobile app, you can use a smaller icon size of 16 pixels
(wide) by 16 pixels (high).
Thumbnail Image
The thumbnail image associated with a canvas app feed item is displayed when someone accesses your canvas app in the feed. If
specified, this image appears next to the feed item title and description.
We recommend that you use an image of size 120 pixels (wide) by 120 pixels (high) or smaller.
SEE ALSO:
Introducing Canvas
Resizing a Canvas App
Canvas App Process
Canvas App Process
In the process of creating, publishing, installing, and running a canvas app, there are actions required by the developer, the administrator,
and the user, as shown in the following diagram.
6
Canvas App ProcessIntroducing Canvas
7
Canvas App ProcessIntroducing Canvas
Once the user is authenticated inside the Canvas app, the browser may restrict the app from receiving third-party cookies or using local
storage. See Alternatives to Cookies for User Tracking on page 43.
SEE ALSO:
Introducing Canvas
Quick Start (currently unavailable)
Quick StartAdvanced
Canvas Personal App Process
Enabling Canvas Personal Apps within an Organization
Package the Canvas App
Canvas Personal Apps
Canvas personal apps let you create connected apps that are designed specifically for end users across organizations. With a canvas
personal app, you make your own app available for installation without relying on organization administrators for distribution.
Previously, only administrators could install canvas apps. Administrators can still install canvas apps, but now developers can create
canvas personal apps that end users can install themselves.
End users install and use canvas personal apps right from the Chatter tab (provided that they have appropriate permissions in Salesforce).
When end users install the app, they are prompted to allow the app to use their Salesforce data.
Creating a canvas personal app is similar to creating any canvas app, except that:
Users are prompted to approve or deny a canvas personal app the first time they access the app, regardless of whether youve used
OAuth or signed request as the access method. This is because initial access triggers the OAuth approval flow. After initial access,
users are identified transparently and are not prompted for approval or credentials (as long as they are logged in to Salesforce).
With a canvas personal app, only the apps metadata is installed, without the other package components (such as Apex classes and
Visualforce components). This facilitates widespread installation of the app, and lets you limit the apps functionality to only what
the end user needs.
For information about managed packages, see Use Managed Packages to Develop Your AppExchange Solution.
Canvas Personal App Process
Creating a canvas personal app is similar to creating any canvas app. However, you distribute a canvas personal app directly to end
users, who install it via a link that you provide, integrating the app with their Salesforce data. After the app is installed, end users run
it right from the Chatter tab.
Enabling Canvas Personal Apps within an Organization
The administrator of an organization controls whether users can install canvas personal apps within that organization. Before
attempting to create a canvas personal app, verify that the organization administrator has enabled canvas personal apps.
Making an App a Canvas Personal App
You (the apps developer) can enable an app as a canvas personal app when you first create it, or make your existing canvas app a
canvas personal app. This process involves ensuring that an organization preference is active, and activating a setting on the apps
Detail page.
Uninstalling a Canvas Personal App
When a user installs and allows a canvas personal app, a refresh token is created, which in turn generates an OAuth token. To stop
end users from accessing the app, this refresh token must be revoked. This action effectively uninstalls the canvas personal app.
8
Canvas Personal AppsIntroducing Canvas
Canvas Personal App Process
Creating a canvas personal app is similar to creating any canvas app. However, you distribute a canvas personal app directly to end users,
who install it via a link that you provide, integrating the app with their Salesforce data. After the app is installed, end users run it right
from the Chatter tab.
Heres how to make canvas personal apps available to end users.
1. You verify that the organization administrator has enabled personal apps within the destination organization. For details, see Enabling
Canvas Personal Apps within an Organization on page 9.
2. You create the app, and specify that its a canvas personal app. For details, see Making an App a Canvas Personal App on page 10.
3. The end user clicks the app link that youve provided. For example, the link could be a button on your website, or delivered in an
email. Clicking the link invokes the OAuth approval process for the app. Heres an example of what a link to the app looks like:
https://MyDomainName.my.salesforce.com/services/oauth2/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>
4. When prompted, the end user approves the app and allows access to Salesforce data.
5. The OAuth approval flow triggers the canvas installer in asynchronous mode. The canvas installer gets context information for the
app from the API, and installs the apps metadata. The app is installed in the background, and the end user receives an email when
installation is complete.
Note: Only the canvas personal apps metadata is installed. Any additional components that are typically packaged with a
canvas app are not installed with the app. This means that users get only the functionality they need, and installation is quick
and lightweight. However, if the administrator chooses to install the canvas personal app for the entire organization, the
additional package components are installed, as with any canvas app.
6. The user starts using the canvas personal app by clicking the apps icon from the Chatter tab.
SEE ALSO:
Canvas App Process
Making an App a Canvas Personal App
Enabling Canvas Personal Apps within an Organization
The administrator of an organization controls whether users can install canvas personal apps within that organization. Before attempting
to create a canvas personal app, verify that the organization administrator has enabled canvas personal apps.
Heres how the organization administrator enables canvas personal apps.
1. From Setup, enter Connected Apps in the Quick Find box, then select the option for managing connected apps.
2. Next to App Access Settings, click Edit.
3. Select the Allow users to install canvas personal apps checkbox.
9
Canvas Personal App ProcessIntroducing Canvas
4. Click Save.
After the administrator has done these steps, you can designate your canvas app as a canvas personal app. For details, see Making an
App a Canvas Personal App on page 10.
SEE ALSO:
User Permissions Required
Canvas Personal App Process
Making an App a Canvas Personal App
You (the apps developer) can enable an app as a canvas personal app when you first create it, or make your existing canvas app a canvas
personal app. This process involves ensuring that an organization preference is active, and activating a setting on the apps Detail page.
In order for you to make an app a canvas personal app:
The administrator for the apps destination organization must enable canvas personal apps in that organization. To do so, from Setup,
enter Connected Apps in the Quick Find box, then select the option for managing connected apps.
You need to enable the app as a canvas personal app, as follows.
1. In the Locations field, select Chatter Tab. If this is a canvas personal app, Chatter Tab is the only location where a canvas personal
app can appear.
2. Under Canvas App Settings, select the Enable as a Canvas Personal App checkbox. This setting is available only when Chatter
Tab is selected as the apps location.
10
Making an App a Canvas Personal AppIntroducing Canvas
After youve created the canvas personal app and provided a link to it, end users can access the app and install it themselves.
SEE ALSO:
Canvas Personal App Process
Uninstalling a Canvas Personal App
When a user installs and allows a canvas personal app, a refresh token is created, which in turn generates an OAuth token. To stop end
users from accessing the app, this refresh token must be revoked. This action effectively uninstalls the canvas personal app.
Heres how a canvas personal app can be uninstalled.
The organization administrator removes the refresh token for one or all users in the organization via the Connected Apps OAuth
Usage page in Setup.
End users revoke the canvas personal app from their Connected Apps list.
The administrator explicitly uninstalls the canvas personal app from the organization via the Manage Apps page in Setup. This action
removes the app from the organization.
If an organization administrator disables canvas personal apps within the organization after a canvas personal app is installed, the canvas
personal app continues to work. This is because the apps version number and URL persist, regardless of how the organization preference
for canvas personal apps is set.
However, the administrator can explicitly uninstall the app, completely removing it from use within the organization.
SEE ALSO:
Signed Request Authentication
11
Uninstalling a Canvas Personal AppIntroducing Canvas
CHAPTER 2 Quick Start (currently unavailable)
In this chapter ...
Important: The Heroku Quick Start feature is currently unavailable.
Prerequisites
This simple quick start shows you how to get started with Canvas by using the Heroku Quick Start. The
Heroku Quick Start creates a hello world app on Heroku in either Java or Ruby, depending on the
template you select. At the same time, it creates a corresponding canvas app in Salesforce.
Create the App
Set the App Location
The Heroku app is a hello world Web page that calls the Canvas SDK to display information about the
current user and lets you post to the current users Chatter feed.
SEE ALSO:
Prerequisites
Create the App
Set the App Location
12
Prerequisites
Important: The Heroku Quick Start feature is currently unavailable.
You need the appropriate access and tools to complete the quick start steps.
Access to a Developer Edition organization.
To create a Developer Edition org, go to developer.salesforce.com/signup and follow the instructions for signing up
for a Developer Edition organization.
If you have an existing Developer Edition organization, and, from Setup, you dont see the menu item Canvas App Previewer,
contact Salesforce.
Customize Application and Modify All Data user permissions. If youre an administrator, you most likely already have these
permissions. Otherwise, you need to add them so that you can see the Canvas App Previewer and create canvas apps.
A Heroku account. Go here to create a Heroku account: https://api.heroku.com/signup.
Java version 1.6 or 1.7 to run the local instance of the hello world app that you create. (The Heroku instance of the app automatically
downloads the correct version of Java.)
SEE ALSO:
Quick Start (currently unavailable)
Supported Salesforce Editions
Create the App
Create the App
Create the Heroku hello world app and the associated canvas app in Salesforce.
Important: The Heroku Quick Start feature is currently unavailable.
1. In Salesforce, from Setup, enter Canvas App Previewer in the Quick Find box, then select Canvas App Previewer.
2. Click Heroku Quick Start.
3. In the Template field, select Java Quick Start Template.
4. In the Canvas App Name field, enter a unique name of up to 30 characters.
5. In the Heroku App Name field, enter a unique name of up to 30 characters that begins with a letter and contains only lowercase
letters, numbers, and dashes. The newappName must be unique across all Heroku apps. This name becomes part of the URL for
your app, for example, newappName.herokuapp.com.
6. In the Auth Type field, select API Key. Find the API key associated with your account on the Heroku My Account page.
7. Click Create. The app displays in the left navigation pane.
If you see the error Error [Read timed out] executing POST to Heroku clone REST service, then the operation timed out when it tried
to contact Heroku. You can check the status of Heroku at http://status.heroku.com.
8. Click the link to your new app.
The app appears, and you see the message Hello User.FullName, as well as other information about the current user.
13
PrerequisitesQuick Start (currently unavailable)
You just created a canvas appcongratulations! You can see your canvas app only in the Canvas App Previewer until you set the locations
where it can appear by following the steps in Set the App Location. This setting defines where a user sees your app after its installed in
their org.
Behind the scenes, Heroku Quick Start sets the canvas apps Permitted Users, which includes admin-approved users and your
profile. For example, if your user profile is System Administrator, that profile is added to the canvas app you created, and any users with
that profile can access the canvas app.
We recommend that you inspect the code to see how the canvas app works. The source code for the app is available in the
canvas-quickstart-java public GitHub repository. Use the example code to learn how to decode and validate the canvas signed request
in your app.
SEE ALSO:
Quick Start (currently unavailable)
Prerequisites
Canvas Limits
Set the App Location
Set the App Location
Important: The Heroku Quick Start feature is currently unavailable.
In this step, youll specify where your canvas app can display to a user in Salesforce.
1. From Setup, search for Apps in the Quick Find box, then select App Manager in Lightning Experience or Connected Apps
in Salesforce Classic.
2. In the related list, click the dropdown arrow for the app you just created and then click Edit.
3. In the Canvas Apps Settings section, in the Locations field, select where the canvas app can appear to the user. For this
walkthrough, select Chatter Tab.
Chatter FeedThe canvas app appears in the feed. If this option is selected, you must create a CanvasPost feed item and
ensure that the current user has access to the canvas app.
Chatter TabThe canvas app appears in the app navigation list on the Chatter tab. If this option is selected, the canvas app
appears there automatically.
ConsoleThe canvas app appears in the footer or sidebars of a Salesforce console. If this option is selected, you must choose
where the canvas app appears in a console by adding it as a custom console component.
Layouts and Mobile CardsThe canvas app can appear on a page layout or a mobile card. If this option is selected, you choose
where the canvas app appears by adding it to the page layout.
Mobile NavThe canvas app is accessible from the mobile app navigation menu.
Open CTIThe canvas app appears in the call control tool. If this option is selected, you must specify the canvas app in your
call centers definition file for it to appear.
PublisherThe canvas app appears in the Chatter publisher and action bar. If this option is selected, you must also create a
canvas custom action and add it to the global publisher layout or to an objects page layout.
Visualforce PageThe canvas app can appear on a Visualforce page . If you add an <apex:canvasApp> component to
expose a canvas app on a Visualforce page, be sure to select this location for the canvas app; otherwise, youll receive an error.
4. Click Save.
14
Set the App LocationQuick Start (currently unavailable)
Because you selected Chatter Tab, your canvas app now appears in the left navigation pane on the Chatter tab.
SEE ALSO:
Quick Start (currently unavailable)
Create the App
Where Canvas Apps Appear
Quick StartAdvanced
15
Set the App LocationQuick Start (currently unavailable)
CHAPTER 3 Quick StartAdvanced
This advanced quick start shows you how to get started with more of the Canvas features. It takes you
step-by-step through the process of creating, packaging, uploading, installing, and running a canvas
In this chapter ...
Prerequisites
app. The sample canvas app is a hello world Web page that calls the Canvas SDK to display the current
users name.
Clone the Project
from GitHub
In this example, youll:
Run the Web App
Locally
Clone the hello world app from GitHub
Run the app on a local Web server
Create the Canvas
App
Expose the Web app as a canvas app in your Salesforce development organization and test it in the
Canvas App Previewer
Configure Who Can
Access the Canvas
App
Deploy the Web app to Heroku
Package and upload the canvas app
Deploy the Web App
to Heroku
Install the canvas app in another Salesforce organization and run it as a user would
The steps in this quick start assume youre using Windows. You can use another OS, but there might be
some minor differences in the steps.
SEE ALSO:
Introducing Canvas
Prerequisites
Update the Canvas
App
Package the Canvas
App
Upload the Canvas
App Package
Install the Canvas
App
Configure Who Can
Access the Installed
Canvas App
16
Prerequisites
You need the appropriate access and tools to complete the quick start steps.
Access to a Developer Edition organization for developing your canvas app. To install your canvas app, youll need a Developer
Edition organization other than the one you use to create the canvas app.
To create a Developer Edition org, go to developer.salesforce.com/signup and follow the instructions for signing up
for a Developer Edition organization.
If you have an existing Developer Edition organization, and, from Setup, you dont see the menu item Canvas App Previewer,
contact Salesforce.
Customize Application and Modify All Data user permissions. If youre an administrator, you most likely already have these
permissions. Otherwise, you need to add them so that you can see the Canvas App Previewer and create canvas apps.
Git installed. Go here to install and configure Git: https://help.github.com/articles/set-up-git.
After you install Git, you might need to configure SSH by using the keygen tool. See
https://help.github.com/articles/generating-ssh-keys for more information. If youre using Windows,
this tool is located in the Git \bin directory, which isnt added to the path after you install Git. Add the \bin directory to your
path by using Control Panel. Depending on your installation directory, the path might be something like C:\Program Files
(x86)\Git\bin.
A GitHub account to clone the code example. Go here to set up a GitHub account: https://github.com/plans.
Maven 3.0 or greater installed to package the sample app. Go here to download and install Maven:
http://maven.apache.org/download.html.
A Heroku account if you want to run the app from Heroku. Go here to create a Heroku account:
https://api.heroku.com/signup.
Heroku Toolbelt if you want to manage the Heroku app from the command line. Go here to download and install Heroku Toolbelt:
https://toolbelt.heroku.com.
SEE ALSO:
Quick StartAdvanced
Supported Salesforce Editions
Clone the Project from GitHub
Clone the Project from GitHub
The hello world sample project is part of the Canvas SDK, which is located on GitHub. From GitHub, clone the project to make a copy
of it on your local machine.
1. Log in to https://github.com.
2. Locate the project that contains the Canvas SDK and code examples by going to:
https://github.com/forcedotcom/SalesforceCanvasFrameworkSDK.
3. To clone the Canvas SDK repository, follow the instructions in the projects README.md file.
17
PrerequisitesQuick StartAdvanced
After you clone the project, the SalesforceCanvasFrameworkSDK directory should contain a subdirectory named src and
files, such as pom.xml and README.md.
SEE ALSO:
Quick StartAdvanced
Prerequisites
Run the Web App Locally
Run the Web App Locally
In this step, youll package the Web app using Maven and then run it locally using Jetty. When you package the Web app, the process
downloads all the components needed to run the Web app, including Jetty.
1. Open a command window and navigate to c:\SalesforceCanvasFrameworkSDK.
2. Enter the command mvn package. Youll see output in the command window as Maven packages the app and its dependent
components. If the process completes successfully, youll see something like this:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 28.016s
[INFO] Finished at: Tue Jul 03 08:00:42 PDT 2012
[INFO] Final Memory: 8M/59M
[INFO] ------------------------------------------------------------------------
3. To use Jetty to run the app, youll need to enable local SSL support. This step only needs to be done once per app, so if youve already
done this, skip this step. Ensure that the command window is open and youre in the directory
c:\SalesforceCanvasFrameworkSDK.
4. Run the following command: keytool -keystore keystore -alias jetty -genkey -keyalg RSA.
After you run this command, youll be prompted for the following information. Enter 123456 for the keystore password and yes
to confirm at the end. When prompted, Enter key password for <jetty>, press Enter to use the keystore password. For the other
information, you can enter values or leave them blank.
Enter keystore password: <Choose Your Password>
Re-enter new password: <Choose Your Password>
What is your first and last name?
[Unknown]: <Enter First and Last Name>
What is the name of your organizational unit?
[Unknown]: <Enter an Org Unit>
What is the name of your organization?
[Unknown]: <Enter an Org>
What is the name of your City or Locality?
[Unknown]: <Enter a City>
What is the name of your State or Province?
[Unknown]: <Enter a State>
What is the two-letter country code for this unit?
[Unknown]: <Enter a Country>
Is CN=XXXX, OU=XXXX, O=XXXX, L=XXXX, ST=XX, C=XX correct?
[no]: yes
18
Run the Web App LocallyQuick StartAdvanced
Enter key password for <jetty>
(RETURN if same as keystore password):
This creates a file named keystore in the directory c:\SalesforceCanvasFrameworkSDK. The keystore is used by
Jetty for SSL support.
5. Run the Web server by entering this command: target\bin\webapp.bat (Windows) or sh target/bin/webapp
(Unix/OS X).
If youre using Unix/OS X, you may need to add execute permissions to webapp before you can run it. Use this command to do
so: chmod +x target/bin/webapp.
6. Verify that the app is running by opening a browser and navigating to the following URL:
https://localhost:8443/examples/hello-world/index.jsp.
Depending on your browser and security settings, you might need to add a security exception because youre running a site with
an unsigned SSL certificate.
You should see a message that says, This App must be invoked via a signed request! This is an indication that the Web app is
running locally. This message appears because the app is designed to receive a signed request from Salesforce, therefore, the app
wont run outside of the Salesforce canvas environment.
SEE ALSO:
Quick StartAdvanced
Clone the Project from GitHub
Create the Canvas App
Create the Canvas App
In this step, you create the canvas app in your Salesforce organization. To create a canvas app, you need the Customize Application and
Modify All Data user permissions.
1. In Salesforce, from Setup, enter Apps in the Quick Find box, then select App Manager.
2. Click New Connected App.
3. In the Connected App Name field, enter Hello World.
4. Accept the default API Name of Hello_World. This is the internal name of the canvas app and cant be changed after you save it.
5. In the Contact Email field, enter your email address.
6. In the Logo Image URL field, enter https://localhost:8443/images/salesforce.png. This is the default
Salesforce No Software image. This image appears on the installation screen and on the detail screen for the app.
7. In the Icon URL field, enter https://localhost:8443/examples/hello-world/logo.png. This is the default
Salesforce No Software image.
This is the image that appears next to the app name in the user interface. If you leave this field blank, a default cloud image appears
next to the app name.
8. In the API (Enable OAuth Settings) section, select the Enable OAuth Settings field.
9. In the Callback URL field, enter https://localhost:8443/sdk/callback.html.
10. In the Selected OAuth Scopes field, select Access the identity URL service (id, profile, email, address, phone).
19
Create the Canvas AppQuick StartAdvanced
11. In the Canvas App Settings section, select Canvas.
12. In the Canvas App URL field, enter https://localhost:8443/examples/hello-world/index.jsp.
13. In the Access Method field, select Signed Request (Post).
14. In the Locations field, select Chatter Tab.
15. Save the app, then click Continue.
After the canvas app is saved, the detail page appears.
16. On the detail page for the canvas app, click Manage Consumer Details, and then verify your identity.
17. Select the consumer secret value and enter CTRL+C to copy it. The consumer secret is used in the app to authenticate.
18. Go to the command window and stop the Jetty Web server by entering CTRL+C. At the prompt, enter Y.
19. Create an environment variable named CANVAS_CONSUMER_SECRET and set that value to the consumer secret you just copied.
To do this in Windows, in the command window, enter set CANVAS_CONSUMER_SECRET=value_you_just_copied.
If youre using Unix/OS X, set the environment variable with the command export
CANVAS_CONSUMER_SECRET=value_you_just_copied.
The hello world page
(c:\SalesforceCanvasFrameworkSDK\src\main\webapp\examples\hello-world\index.jsp) uses
the consumer secret, as shown in the following code:
<%@ page import="canvas.SignedRequest" %>
<%@ page import="java.util.Map" %>
<%
// Pull the signed request out of the request body and verify and decode it.
Map<String, String[]> parameters = request.getParameterMap();
String[] signedRequest = parameters.get("signed_request");
if (signedRequest == null) {%>
This app must be invoked via a signed request!<%
return;
}
String yourConsumerSecret=System.getenv("CANVAS_CONSUMER_SECRET");
String signedRequestJson = SignedRequest.verifyAndDecodeAsJson(signedRequest[0],
yourConsumerSecret);
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>Hello World Canvas Example</title>
<link rel="stylesheet" type="text/css" href="/sdk/css/connect.css" />
<script type="text/javascript" src="/sdk/js/canvas-all.js"></script>
<!-- Third part libraries, substitute with your own -->
<script type="text/javascript" src="/scripts/json2.js"></script>
<script>
if (self === top) {
// Not in an iFrame.
20
Create the Canvas AppQuick StartAdvanced
alert("This canvas app must be included within an iFrame");
}
Sfdc.canvas(function() {
var sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.byId('username').innerHTML = sr.context.user.fullName;
});
</script>
</head>
<body>
<br/>
<h1>Hello <span id='username'></span></h1>
</body>
</html>
20. Restart the Web server by entering this command: target\bin\webapp.bat (Windows) or sh target/bin/webapp
(Unix/OS X).
SEE ALSO:
Quick StartAdvanced
Run the Web App Locally
Where Canvas Apps Appear
User Permissions Required
Canvas Limits
Configure Who Can Access the Canvas App
Configure Who Can Access the Canvas App
Youve created the canvas app in Salesforce. Now lets configure access for specific users.
1. In Salesforce, from Setup, enter Connected Apps in the Quick Find box, then select Manage Connected Apps.
2. In the Connected Apps list, click Edit next to the Hello World app.
3. In the OAuth Policies section, click the Permitted Users dropdown menu and select Admin approved users are pre-authorized.
Click OK on the pop-up message that appears.
We select Admin approved users are pre-authorized so users dont see the canvas app until we give them permission. If we
select All users may self-authorize, all users in the org can authorize the app after they sign in.
4. Save your settings and return to the Manage Connected Apps page.
5. To view the Connected App Detail page for your Hello World app, click Hello World in the Connected Apps list.
On the Connected App Detail page, you can define who can see your canvas app by managing profiles and permission sets.
6. In the Profiles section, click Manage Profiles.
In this example, we assume that your profile is System Administrator.
7. Select the System Administrator profile and save your settings.
8. From Setup, enter Canvas App Previewer in the Quick Find box, then select Canvas App Previewer. You can use the
Canvas App Previewer to test your canvas app before you publish it.
21
Configure Who Can Access the Canvas AppQuick StartAdvanced
9. From the Canvas App Previewer list, click Hello World.
The app launches, and the message Hello User.FullName appears. The canvas app works in this context because when
you click the app name in the message previewer, the signed request is sent to the endpoint
https://localhost:8443/examples/hello-world/index.jsp.
After you configure access, you can see the canvas app in the Canvas App Previewer and on the Chatter tab in your development
organization.
SEE ALSO:
Quick StartAdvanced
Create the Canvas App
Deploy the Web App to Heroku
Deploy the Web App to Heroku
Warning: Using dynos to complete this tutorial counts toward your usage. Scale your dynos to 0 as soon as youre done to
minimize costs.
Important: Where possible, we changed noninclusive terms to align with our company value of Equality. We maintained certain
terms to avoid any effect on customer implementations.
In this walkthrough, you previously ran the hello world Web app locally before adding it as a canvas app and testing it. Now that your
canvas app works locally, youre ready to deploy your hello world Web app to Heroku and run it from there. Heres how you do it.
1. If you havent already, log into Heroku and install Heroku Toolbelt following the links in the Prerequisites.
2. Open a command window, navigate to c:\SalesforceCanvasFrameworkSDK, and enter the following command: git
init. This re-initializes the directory as a Git repository.
3. In the command window, enter the following command: heroku create. This creates a new shell app on Heroku.
Confirmation that the app was created looks like this:
Creating deep-samurai-7923... done, stack is cedar
http://deep-samurai-7923.herokuapp.com/ | [email protected]:deep-samurai-7923.git
Git remote heroku added
4. To rename this Heroku app, enter the following command in the command window: heroku rename newAppName -—app
oldAppName.
In this example, oldAppName is deep-samurai-7923. The newAppName you create must begin with a letter and can only contain
lowercase letters, numbers, and dashes. Youll see a confirmation of the renaming that looks similar to this:
http://newappName.herokuapp.com/ | [email protected]:newappName.git
The newappName must be unique across all Heroku apps. This name becomes part of the URL for your app, for example,
newappName.herokuapp.com.
5. Run the following command in the command window: git add -A. This adds the entire SalesforceCanvasFrameworkSDK project
to the Git repository. If youre working in the Windows environment, you might see some messages about LF (line feeds) being
replaced by CRLF (carriage return line feeds).
6. Enter the following command in the command window to commit the changes along with a comment: git commit —m
MyChangeComments.
22
Deploy the Web App to HerokuQuick StartAdvanced
7. Enter the following command in the command window to deploy the changes to Heroku: git push heroku master.
If the process completes successfully, youll see something like this:
[INFO] -------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] -------------------------------------------------
[INFO] Total time: 13.188s
[INFO] Finished at: Sat Feb 09 21:14:23 UTC 2013
[INFO] Final Memory: 11M/490M
[INFO] -------------------------------------------------
If you receive a permission denied error message, you may need to set up your SSH key and add it to Heroku. See
https://devcenter.heroku.com/articles/keys.
8. Open a command window, and set the Heroku environment variable that contains the consumer secret by entering this command
and replacing consumer_secret_value with the value you just copied: heroku config:add
CANVAS_CONSUMER_SECRET=consumer_secret_value.
To get the consumer secret for the canvas app, from Setup, enter Apps in the Quick Find box, then select Apps and click the
Hello World app. Youll see the Consumer Secret field in the OAuth Settings section.
9. Verify that the app is running in Heroku by opening a browser and navigating to the following URL:
https://newappName.herokuapp.com/examples/hello-world/index.jsp.
You should see a message that says, This App must be invoked via a signed request! This is an indication that the app is running
in Heroku. This message appears because the app is designed to receive a signed request from Salesforce canvas environment.
SEE ALSO:
Quick StartAdvanced
Configure Who Can Access the Canvas App
Update the Canvas App
Update the Canvas App
In this step, youll update the canvas app to run the hello world app thats now running on Heroku.
1. In Salesforce, from Setup, enter Apps in the Quick Find box, then select Apps.
2. In the Connected Apps related list, click Hello World.
3. Click Edit.
4. In the Logo Image URL field, enter https://appName.herokuapp.com/images/salesforce.png. This is
the default Salesforce No Software image. This image appears on the installation screen and on the detail screen for the app. The
appName is the name of Heroku app that you just created.
5. In the Icon URL field, enter https://appName.herokuapp.com/examples/hello-world/logo.png. This
is the default Salesforce No Software image.
This is the image that appears next to the app name on the Chatter tab or in the Canvas App Previewer. If you leave this field blank,
a default cloud image appears next to the app name. The appName is the name of Heroku app that you just created.
6. In the Callback URL field, enter https://appName.herokuapp.com/sdk/callback.html. The appName is
the name of Heroku app that you just created.
23
Update the Canvas AppQuick StartAdvanced
7. In the Canvas App URL field, enter https://appName.herokuapp.com/examples/hello-world/index.jsp.
The appName is the name of Heroku app that you just created.
8. Click Save. After the canvas app is saved, the detail page appears.
9. In Salesforce, from Setup, enter Canvas App Previewer in the Quick Find box, then select Canvas App Previewer.
You can use the Canvas App Previewer to test out your canvas app before repackaging it.
10. Click the Hello World link on the left.
The app should appear and youll see the message Hello User.FullName. The canvas app works in this context because
when you click the app name in the previewer, the signed request is sent to the endpoint
https://appName.herokuapp.com/examples/hello-world/index.jsp.
In this example, were using the same canvas app that we just created, but updating it to point to the hello world Web app running
on Heroku. Therefore, the consumer secret that we previously added to our hello world app doesnt need to be updated.
If you want to create a new canvas app in Salesforce that displays the hello world app running on Heroku, then go to Create the Canvas
App to create the new app, update the consumer secret in the app, and then deploy the changes to Heroku.
SEE ALSO:
Quick StartAdvanced
Deploy the Web App to Heroku
Package the Canvas App
Package the Canvas App
Now that youve created the canvas app, tested it in the Canvas App Previewer, and deployed it to Heroku, youre ready to package and
distribute it. Packaging is the first step in making your canvas app available for installation in another organization. For more information
about packaging, see the Use Managed Packages to Develop Your AppExchange Solution.
1. In Salesforce, from Setup, enter Packages in the Quick Find box, then select Packages and click New.
Tip: To package your canvas app for installation in other organizations, you must create a namespace prefix. A namespace
prefix can only be defined in a Developer Edition organization. For more information, see the topic Registering a Namespace
Prefix in the online help.
2. Set the Package Name field to Hello World Package and accept the defaults for the other fields.
3. Select the Managed field to make the package the managed package for the organization.
4. A prompt appears stating youre only allowed one managed package. Click OK.
5. Click Save.
6. The package is empty, so click Add.
7. In the Component Type field, select Connected App.
8. Select the checkbox next to the Hello World app and click Add To Package. The Package Detail screen appears. From Setup, enter
Packages in the Quick Find box, then select Packages to see the new managed package.
24
Package the Canvas AppQuick StartAdvanced
Now youre ready to upload the package you created and get the installation link. Use the installation link to install your canvas app in
another organization.
SEE ALSO:
Quick StartAdvanced
Update the Canvas App
Use Managed Packages to Develop Your AppExchange Solution
Upload the Canvas App Package
Distributing Your CanvasLifecycleHandler Class
Upload the Canvas App Package
Now that youve packaged the canvas app, youre ready to upload the package. This creates an installation link that you can provide to
anyone who needs to install your canvas app in their organization.
1. In Salesforce, from Setup, enter Packages in the Quick Find box, then select Packages.
2. In the Packages list, click the Hello World Package link.
3. On the Package Detail page, click Upload to publish the managed package.
4. In the Version Name field, enter Winter 2014 Beta. Keep the default Version Number of 1.0 and Release Type of ManagedBeta.
5. Click Upload.
Note: A canvas app can only be installed in an organization other than the one youre developing in.
After the upload completes, the Version Detail page appears. The Installation URL field contains the URL that you can use to install the
canvas app in another organization. Youll also receive a notification email that contains the installation URL.
SEE ALSO:
Quick StartAdvanced
Package the Canvas App
Publishing Your App
Install the Canvas App
Install the Canvas App
Uploading the packaged canvas app creates the installation link. You can then use this link to install the canvas app in another organization.
Beta packages can only be installed in sandbox or Developer Edition organizations, otherwise, youll receive an error.
1. Open a browser and enter the canvas app installation URL in the browser address bar. If youre in the process of developing your
canvas app, be sure to log out of your development organization before you install the app.
The installation URL looks something like:
https://login.instance.salesforce.com/services/packaging/installPackage.apexp?p0=04eU0000000AWNA.
2. When prompted, enter your login credentials for the organization in which youre installing the package.
25
Upload the Canvas App PackageQuick StartAdvanced
3. The Package Installation Details page appears. In the Package Components list, you should see the Hello World canvas app. Click
Continue.
4. Click Next and then click Install.
After the package installation completes successfully, youll receive an email notification.
SEE ALSO:
Quick StartAdvanced
Upload the Canvas App Package
Supported Salesforce Editions
Configure Who Can Access the Installed Canvas App
Configure Who Can Access the Installed Canvas App
Youve installed the canvas app in your Salesforce organization, but no one can see it until you configure user access.
1. In Salesforce, from Setup, enter Connected Apps in the Quick Find box, then select the option for managing connected
apps.
2. Click the Hello World app, and then click Edit.
3. In the Permitted Users field, select Admin approved users are pre-authorized. Click OK on the pop-up message that appears.
4. Click Save.
Now youll define who can see your canvas app. This can be done using profiles and permission sets. In this example, well allow
anyone with the System Administrator to access the app.
5. On the Connected App Detail page, in the Profiles related list, click Manage Profiles.
6. Select the System Administrator profile and click Save.
7. Click the Chatter tab.
8. Click the Hello World link on the left.
The app appears and youll see the message Hello User.FullName.
SEE ALSO:
Quick StartAdvanced
Install the Canvas App
26
Configure Who Can Access the Installed Canvas AppQuick StartAdvanced
USING CANVAS
CHAPTER 4 Canvas SDK
Canvas is a set of tools that enable you to integrate your apps within Salesforce. This framework includes
an SDK that you can use to authenticate your app and retrieve data from Salesforce.
In this chapter ...
Referencing the
Canvas SDK
Important: To prepare your Canvas apps for the new web browser restrictions on third-party
cookies, see How Third-Party Cookie Restrictions Impact Salesforce Canvas Apps in Salesforce Help.
Authentication
The Canvas SDK and code examples are available on GitHub at
https://github.com/forcedotcom/salesforcecanvasframeworksdk.
Getting Context in
Your Canvas App
Cross-Domain XHR
The Canvas SDK is versioned and matches the API version in each release. The current version is 61.0. To
check the version of the SDK that you have, call the version method.
SEE ALSO:
Referencing the Canvas SDK
Authentication
Getting Context in Your Canvas App
Cross-Domain XHR
Resizing a Canvas App
Implementing Canvas App Events
Alternatives to
Cookies for User
Tracking
Resizing a Canvas
App
Implementing
Canvas App Events
Using Streaming API
in a Canvas App
Debugging in a
Canvas App
Using the <select>
Tag in a Canvas App
27
Referencing the Canvas SDK
The Canvas SDK is available on GitHub, and you have two options for referencing it from your canvas app.
Host the SDK on your own Web server and access it there
Access the SDK hosted on the Salesforce server
For example, heres what the include statement looks like if you host the SDK on your own Web server:
<script type="text/javascript" src="/sdk/js/canvas-all.js"></script>
Heres what the include statement looks like if you reference the hosted SDK:
<script type="text/javascript"
src="https://<instance>.salesforce.com/canvas/sdk/js/61.0/canvas-all.js"></script>
The ability to reference the SDK on the Salesforce server is useful when you want to include one of the SDK files in a Web app or from a
Visualforce page.
SEE ALSO:
Canvas SDK
Authentication
Authentication
When you create a Canvas app, you can use the signed request authentication method or the OAuth 2.0 authentication method.
Important: If your Canvas app URL contains a URL fragment identifier (#), then the hash mark (#) and all characters that follow
are stripped from the URL during the authentication flow. To prevent unexpected behavior, avoid using hash marks (#) in a Canvas
app URL.
Signed requestThe default method of authentication for Canvas apps. The signed request containing the consumer key, access
token, and other contextual information is provided to the Canvas app in one of these ways.
The administrator allows access to the Canvas app for the user.
The user approves the Canvas app in the OAuth flow.
OAuth 2.0Canvas apps can use the OAuth 2.0 protocol to authorize and acquire access tokens. For more information about OAuth
and the Lightning Platform, see Authorize Apps with OAuth.
Signed Request Authentication
Signed request is the default authorization method for Canvas apps. The signed request authorization flow varies depending on
whether the administrator gives users access to the Canvas app or if users can self-authorize. You can verify signed request information
with a client secret, then use signed requests to customize the app and make subsequent calls to Salesforce.
OAuth 2.0 Authorization
Canvas supports the OAuth 2.0 web server flow and the OAuth 2.0 user-agent flow.
28
Referencing the Canvas SDKCanvas SDK
SAML Single Sign-On for Canvas Apps
Whether you use signed request or OAuth authorization, you can use SAML-based single sign-on (SSO) to provide your users with
a seamless authentication flow. You can leverage Salesforce as an identity provider or as a service provider. SAML SSO enables you
to give your users automatic authentication into your canvas app via SAML and authentication into Salesforce via the signed request.
SEE ALSO:
Canvas SDK
Understanding Authentication
Canvas App User FlowSigned Request
Canvas App User FlowOAuth
Signed Request Authentication
Signed request is the default authorization method for Canvas apps. The signed request authorization flow varies depending on whether
the administrator gives users access to the Canvas app or if users can self-authorize. You can verify signed request information with a
client secret, then use signed requests to customize the app and make subsequent calls to Salesforce.
Important: If your Canvas app URL contains a URL fragment identifier (#), then the hash mark (#) and all characters that follow
are stripped from the URL during the authentication flow. To prevent unexpected behavior, avoid using hash marks (#) in a Canvas
app URL.
POST or GET BehaviorWhen the User Must
Approve the Canvas
App
Canvas App
Accessibility
Permitted Users Value
Salesforce performs a POST to the Canvas app
with all the authorization information contained
NeverThe app is accessible to
users as soon as the
Admin-approved users are
pre-authorized
in the body of the signed request, including the
refresh token.
administrator installs it
in the organization and
configures which users
can see it. Users dont
approve or deny access.
If the user previously approved the app and
access hasnt expired or been revoked, Salesforce
The app is accessible to
all users, but the user is
All users can self-authorize
The first time that
the user opens the
app
prompted to approve or
deny access to the app.
performs a POST to the Canvas app with a signed
request payload.
If the user hasnt approved the app, or if access
has expired or been revoked, Salesforce performs
The administrator
revokes the access
token
a GET to the Canvas app URL. The Canvas app
The administrator
sets a time limit on
must handle the GET by accepting the call and
looking for the URL parameter
the token and that
_sfdc_canvas_authvalue. If the Canvas
time limit is
exceeded
app receives this parameter value, the Canvas
app initiates the approve or deny OAuth flow.
_sfdc_canvas_authvalue =
user_approval_required
29
Signed Request AuthenticationCanvas SDK
POST or GET BehaviorWhen the User Must
Approve the Canvas
App
Canvas App
Accessibility
Permitted Users Value
After the OAuth flow is initiated and the user
approves the app, the Canvas app calls the
repost() method with a parameter of true
to retrieve the signed request.
The signed request is a string of these elements concatenated.
The Canvas app consumer secret encrypted with the HMAC SHA256 algorithm
A period (.)
The context and authorization token JSON encoded in Base64
The signed request looks similar to this string, although it can be longer:
9Rpl6rE7R2bSNjoSfYdERk8nffmgtKQNhr5U/5eSJPI=.eyJjb250ZXh0Ijp7InVzZXIiOnsibGFuZ3V...
Signed request considerations:
Salesforce performs an HTTP POST or GET when invoking the Canvas app URL, depending on the Permitted Users value and whether
the refresh token is returned.
Server-side code verifies and decodes the request.
After the app is invoked, you can request a signed request on demand by using the SDK.
Canvas App User FlowSigned Request
Verifying and Decoding a Signed Request
Requesting a Signed Request
If your canvas app is set to use signed request for authentication, you can request a signed request on demand by using the SDK.
Your app can ask Salesforce to resend the signed request that was used when your app was loaded or to send a new signed request.
Requesting a signed request is useful when you are refreshing an expired session or getting authentication information after your
app has been redirected.
SEE ALSO:
Authentication
Verifying and Decoding a Signed Request
Canvas App User FlowSigned Request
Requesting a Signed Request
Canvas App User FlowSigned Request
This diagram shows the user flow for a canvas app that uses signed request authentication.
30
Signed Request AuthenticationCanvas SDK
SEE ALSO:
Signed Request Authentication
SignedRequest
Verifying and Decoding a Signed Request
Verifying and Decoding a Signed Request
When using a signed request, Salesforce delivers the user context and authentication information to your canvas app URL. To ensure
that the signed request is valid, you must verify that the signed request was signed using your specific canvas app consumer secret. If
the correct consumer secret was used, then you can trust the context; otherwise, you can assume that the request was not initiated by
Salesforce. To verify and decode the signed request, your application should:
1. Receive the POST message that contains the initial signed request from Salesforce.
2. Split the signed request on the first period. The result is two strings: the hashed Based64 context signed with the consumer secret
and the Base64 encoded context itself.
3. Use the HMAC SHA-256 algorithm to hash the Base64 encoded context and sign it using your consumer secret.
31
Signed Request AuthenticationCanvas SDK
4. Base64 encode the string created in the previous step.
5. Compare the Base64 encoded string with the hashed Base64 context signed with the consumer secret you received in step 2.
If the two values are the same, then you know that the signed request was signed using your consumer secret and can be trusted. From
there, you can Base64 decode the encoded context and parse out any values you need. For more information on those values, see
CanvasRequest. If the two strings are different, then the request was not hashed and signed using your consumer secret, and you should
return the appropriate message to the user.
Functions for Verifying and Decoding
To verify the signed request, you can call the one the following functions found in the Canvas SDK (in
SalesforceCanvasFrameworkSDK\src\main\java\canvas\SignedRequest.java):
verifyAndDecodeReturns a verified and decoded version of the signed request as a Java object.
verifyAndDecodeAsJsonReturns a verified and decoded version of the signed request as a JSON-formatted string.
The following code example shows you how to verify and decode a signed request using the functions in the SDK. This code splits the
signed request string at the period to parse out the signed secret and the Base64 JSON string. It then encrypts the canvas app consumer
secret signed with the HMAC SHA-256 algorithm and compares the encrypted value with the encrypted value sent to you by Salesforce.
If the two values are the same, you know that the context is valid and came from Salesforce. If the two values are different, then the
request didnt come from Salesforce.
/**
*
* The utility method can be used to validate/verify the signed request.
* In this case, the signed request is verified that it's from Salesforce and that
* it has not been tampered with.
*
* This utility class has two methods. One verifies and decodes the request
* as a Java object, the other as a JSON String.
*
*/
public class SignedRequest {
public static CanvasRequest verifyAndDecode(String input, String secret)
throws SecurityException {
String[] split = getParts(input);
String encodedSig = split[0];
String encodedEnvelope = split[1];
// Deserialize the JSON body.
String json_envelope = new String(new Base64(true).decode(encodedEnvelope));
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.reader(CanvasRequest.class);
CanvasRequest canvasRequest;
String algorithm;
try {
canvasRequest = reader.readValue(json_envelope);
algorithm = canvasRequest.getAlgorithm() == null ?
"HMACSHA256" : canvasRequest.getAlgorithm();
} catch (IOException e) {
throw new SecurityException(String.format("Error [%s] deserializing JSON to
Object [%s]", e.getMessage(), CanvasRequest.class.getName()), e);
}
verify(secret, algorithm, encodedEnvelope, encodedSig);
32
Signed Request AuthenticationCanvas SDK
// If we got this far, then the request was not tampered with.
// Return the request as a Java object.
return canvasRequest;
}
public static String verifyAndDecodeAsJson(String input, String secret)
throws SecurityException {
String[] split = getParts(input);
String encodedSig = split[0];
String encodedEnvelope = split[1];
String json_envelope = new String(new Base64(true).decode(encodedEnvelope));
ObjectMapper mapper = new ObjectMapper();
String algorithm;
StringWriter writer;
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String, Object>>() { };
try {
HashMap<String,Object> o = mapper.readValue(json_envelope, typeRef);
writer = new StringWriter();
mapper.writeValue(writer, o);
algorithm = (String)o.get("algorithm");
} catch (IOException e) {
throw new SecurityException(String.format("Error [%s] deserializing
JSON to Object [%s]", e.getMessage(),
typeRef.getClass().getName()), e);
}
verify(secret, algorithm, encodedEnvelope, encodedSig);
// If we got this far, then the request was not tampered with.
// Return the request as a JSON string.
return writer.toString();
}
private static String[] getParts(String input) {
if (input == null || input.indexOf(".") <= 0) {
throw new SecurityException(String.format("Input [%s] doesn't
look like a signed request", input));
}
String[] split = input.split("[.]", 2);
return split;
}
private static void verify(String secret, String algorithm,
String encodedEnvelope, String encodedSig )
throws SecurityException
{
if (secret == null || secret.trim().length() == 0) {
throw new IllegalArgumentException("secret is null, did you
set your environment variable CANVAS_CONSUMER_SECRET?");
}
SecretKey hmacKey = null;
try {
byte[] key = secret.getBytes();
hmacKey = new SecretKeySpec(key, algorithm);
Mac mac = Mac.getInstance(algorithm);
mac.init(hmacKey);
33
Signed Request AuthenticationCanvas SDK
// Check to see if the body was tampered with.
byte[] digest = mac.doFinal(encodedEnvelope.getBytes());
byte[] decode_sig = new Base64(true).decode(encodedSig);
if (! Arrays.equals(digest, decode_sig)) {
String label = "Warning: Request was tampered with";
throw new SecurityException(label);
}
} catch (NoSuchAlgorithmException e) {
throw new SecurityException(String.format("Problem with algorithm [%s]
Error [%s]", algorithm, e.getMessage()), e);
} catch (InvalidKeyException e) {
throw new SecurityException(String.format("Problem with key [%s]
Error [%s]", hmacKey, e.getMessage()), e);
}
// If we got here and didn't throw a SecurityException then all is good.
}
}
Calling the verifyAndDecode Function
The following code shows an example of getting the signed request, and then verifying and decoding the request by using the
verifyAndDecode function.
// From a JSP or servlet.
<%@ page import="canvas.SignedRequest" %>
<%@ page import="java.util.Map" %>
<%
// Pull the signed request out of the request body and verify/decode it.
Map<String, String[]> parameters = request.getParameterMap();
String[] signedRequest = parameters.get("signed_request");
if (signedRequest == null) {%>
This app must be invoked via a signed request!<%
return;
}
String yourConsumerSecret=System.getenv("CANVAS_CONSUMER_SECRET");
String signedRequest = SignedRequest.verifyAndDecode(signedRequest[0],
yourConsumerSecret);
%>
...
// From JavaScript, you can handle the signed request as needed.
var signedRequest = '<%=signedRequestJson%>';
Calling the verifyAndDecodeAsJson Function
The following code shows an example of getting the signed request, verifying and decoding the request by using the
verifyAndDecodeAsJson function, and parsing the returned JSON result.
// From a JSP or servlet.
<%@ page import="canvas.SignedRequest" %>
<%@ page import="java.util.Map" %>
<%
// Pull the signed request out of the request body and verify/decode it.
Map<String, String[]> parameters = request.getParameterMap();
34
Signed Request AuthenticationCanvas SDK
String[] signedRequest = parameters.get("signed_request");
if (signedRequest == null) {%>
This App must be invoked via a signed request!<%
return;
}
String yourConsumerSecret=System.getenv("CANVAS_CONSUMER_SECRET");
String signedRequestJson = SignedRequest.verifyAndDecodeAsJson(signedRequest[0],
yourConsumerSecret);
%>
...
// From JavaScript, you can parse with your favorite JSON library.
var signedRequest = JSON.parse('<%=signedRequestJson%>');
SEE ALSO:
Signed Request Authentication
SignedRequest
Requesting a Signed Request
If your canvas app is set to use signed request for authentication, you can request a signed request on demand by using the SDK. Your
app can ask Salesforce to resend the signed request that was used when your app was loaded or to send a new signed request. Requesting
a signed request is useful when you are refreshing an expired session or getting authentication information after your app has been
redirected.
You can request a signed request on demand by using the refreshSignedRequest() or repost() JavaScript methods in
the SDK. refreshSignedRequest() returns a new signed request via a callback, while repost() asks the parent window to
initiate a new POST to your canvas app and reloads the app page with a refreshed signed request.
Use these methods whenever you need to refresh the signed request for your app. Here are some example scenarios where you might
need to refresh the signed request information.
The OAuth token within a signed request typically expires after two hours. If the OAuth token has expired, and you need to make
additional API requests, you can call refreshSignedRequest() to get a new OAuth token without interrupting the user.
Canvas apps might need to use redirects, particularly when trying to provide single sign-on functionality across multiple systems. If
your canvas app uses redirects, the redirect URL will not receive the original request body that contains the initial signed request
information. You can use the new methods to request the signed request again.
In Summer 14 and later, canvas apps can be user-approved apps. If your user-approved app has not been approved by the user,
your app will not get an initial signed request POST. Instead, your app will need to be approved through OAuth, and then you can
call repost() to get the signed request.
Your canvas app must be configured to use signed request for authentication to use these methods. Youll also need to reference
canvas-all.js in your JavaScript code, as described in Referencing the Canvas SDK.
After a request succeeds, your canvas app must verify the returned SignedRequest information. For more information on verifying signed
request information that is received from Salesforce, see Verifying and Decoding a Signed Request.
35
Signed Request AuthenticationCanvas SDK
Using refreshSignedRequest() to Obtain a Signed Request
Use refreshSignedRequest() to request a new signed request via a callback that you provide. In this example,
refreshSignedRequest() is called with a callback that checks the response code and then parses the signed request into the
hashed Based64 context that is signed with the consumer secret and the Base64 encoded context itself.
// Gets a signed request on demand.
Sfdc.canvas.client.refreshSignedRequest(function(data) {
if (data.status === 200) {
var signedRequest = data.payload.response;
var part = signedRequest.split('.')[1];
var obj = JSON.parse(Sfdc.canvas.decode(part));
}
}
Using repost() to Obtain a Signed Request
Use repost() to instruct the parent window to send a new POST to your canvas app URL. The POSTcontains the signed request that
was used when your app was loaded or a new signed request. Unlike refreshSignedRequest(), using repost() reloads
the canvas app page. The following example calls repost(), asking for the original signed request.
// Gets a signed request on demand, without refreshing the signed request.
Sfdc.canvas.client.repost();
The following example calls repost(), asking for a new signed request.
// Gets a signed request on demand, first by refreshing the signed request.
Sfdc.canvas.client.repost({refresh : true});
SEE ALSO:
Signed Request Authentication
SignedRequest
Verifying and Decoding a Signed Request
OAuth 2.0 Authorization
Canvas supports the OAuth 2.0 web server flow and the OAuth 2.0 user-agent flow.
Important: If your Canvas app URL contains a URL fragment identifier (#), then the hash mark (#) and all characters that follow
are stripped from the URL during the authentication flow. To prevent unexpected behavior, avoid using hash marks (#) in a Canvas
app URL.
When using OAuth with Canvas, you have two options.
Web server flowTo integrate a Canvas app with the Salesforce API, use the OAuth 2.0 web server flow, which implements the
OAuth 2.0 authorization code grant type. With this flow, the server hosting the web app must be able to protect the connected
apps identity, defined by the client ID and client secret. For more information, see OAuth 2.0 Web Server Flow for Web App Integration
in Salesforce Help.
User-agent flowWith the OAuth 2.0 user-agent flow, users authorize a Canvas app to access data using an external or embedded
browser. This flow uses the OAuth 2.0 implicit grant type. For more information, see OAuth 2.0 User-Agent Flow for Desktop or
Mobile App Integration in Salesforce Help.
36
OAuth 2.0 AuthorizationCanvas SDK
Regardless of which OAuth flow that you implement, the Canvas app must provide code for initiating the standards-based OAuth flow.
OAuth considerations include:
Salesforce performs an HTTP GET when invoking the Canvas app URL.
With the user agent flow, all authorization is performed in the browser, and no server-side code is needed.
For more information about OAuth, see Authorize Apps with OAuth in Salesforce Help.
Existing Connected Apps and OAuth
If you have an existing connected app that uses OAuth authorization and you want to expose that app as a Canvas app, you have two
options.
Edit the existing app, and add the Canvas app information to it. Your app can continue to use the same client ID and secret.
Create a new Canvas app, which gets a new client ID and consumer secret. Make sure to update your app with the client ID and
secret.
Canvas App User FlowOAuth
If your canvas app uses OAuth authorization, the user experience varies depending on where the canvas app is located in the user
interface and how user access is set.
Initiating OAuth Flow
SEE ALSO:
Authentication
Canvas App User FlowOAuth
Canvas App User FlowOAuth
If your canvas app uses OAuth authorization, the user experience varies depending on where the canvas app is located in the user
interface and how user access is set.
This diagram shows the user flow for a canvas app that uses OAuth authorization.
37
OAuth 2.0 AuthorizationCanvas SDK
SEE ALSO:
OAuth 2.0 Authorization
Initiating OAuth Flow
38
OAuth 2.0 AuthorizationCanvas SDK
Initiating OAuth Flow
The following code examples show you how to start the authorization process in your canvas app using OAuth.
<html>
<head>
<script type="text/javascript" src="/sdk/js/canvas-all.js"></script>
</head>
<body>
<script>
function loginHandler(e) {
var uri;
if (! Sfdc.canvas.oauth.loggedin()) {
uri = Sfdc.canvas.oauth.loginUrl();
Sfdc.canvas.oauth.login(
{uri : uri,
params: {
response_type : "token",
client_id : "3MVG9lKcPoNINVBLigmW.8dAn4L5HwY VBzxbW5FFdzvU0re2
f7o9aHJNUpY9ACdh.3SUgw5rF2nSsC9_cRqzD",
redirect_uri : encodeURIComponent(
"https://demoapp1234.herokuapp.com/sdk/callback.html")
}});
}
else {
Sfdc.canvas.oauth.logout();
login.innerHTML = "Login";
Sfdc.canvas.byId("oauth").innerHTML = "";
}
return false;
}
// Bootstrap the page once the DOM is ready.
Sfdc.canvas(function() {
// On Ready...
var login = Sfdc.canvas.byId("login"),
loggedIn = Sfdc.canvas.oauth.loggedin(),
token = Sfdc.canvas.oauth.token()
login.innerHTML = (loggedIn) ? "Logout" : "Login";
if (loggedIn) {
// Only displaying part of the OAuth token for better formatting.
Sfdc.canvas.byId("oauth").innerHTML = Sfdc.canvas.oauth.token()
.substring(1,40) + "…";
}
login.onclick=loginHandler;
});
</script>
<h1 id="header">Canvas OAuth App</h1>
<div>
access_token = <span id="oauth"></span>
</div>
<div>
<a id="login" href="#">Login</a><br/>
39
OAuth 2.0 AuthorizationCanvas SDK
</div>
</body>
</html>
SEE ALSO:
OAuth 2.0 Authorization
SAML Single Sign-On for Canvas Apps
Whether you use signed request or OAuth authorization, you can use SAML-based single sign-on (SSO) to provide your users with a
seamless authentication flow. You can leverage Salesforce as an identity provider or as a service provider. SAML SSO enables you to give
your users automatic authentication into your canvas app via SAML and authentication into Salesforce via the signed request.
SAML (Security Assertion Markup Language) is an XML-based standard for user authentication on the Web which allows the exchange
of authorization data between two domains. With this feature you can create a canvas app that begins a standard SAML authentication
flow when opened by a user. After this process completes, the user is authenticated into your Web application.
For canvas apps that use signed request authentication, two methods that are included in the Canvas SDK enable your canvas app to
call into Salesforce to receive a new signed request directly or enable Salesforce to repost the signed request to your Web application
endpoint. This results in a complete end-to-end authentication flow.
refreshSignedRequest Method
Returns a new signed request via a callback. After the SAML SSO process is completed, your app can call this method and receive a
new signed request. This method is intended for developers who need to retrieve the signed request by using a more client-side
JavaScript approach. (The Canvas SDK sends the signed request to your app.)
repost Method
Requests the parent window to initiate a POST to your canvas app and reloads the app page with a refreshed signed request. After
the SAML SSO process is completed, your app can call this method and a new signed request is sent to your app via a POST. This
method is for developers who want to retrieve the signed request using a more server-side approach. (Salesforce POSTs the signed
request to your server.)
Note: The SAML Initiation Method Identity Provider Initiated is not supported for canvas apps on Lightning
Platform sites.
Getting Context in Your Canvas App
When you authenticate your canvas app using signed request, you get the CanvasRequest object (which contains the Context object)
as part of the POST to the canvas app URL. If youre authenticating using OAuth, or you want to make a call to get context information,
you can do so by making a JavaScript call.
Note: Getting context data from the Canvas SDK is the most reliable way to identify users. Browsers may not send your canvas
app cookies or other identifying data. See Alternatives to Cookies for User Tracking on page 43.
The following code sample is an example of a JavaScript call to get context. This code creates a link with the text Get Context which
then calls the Sfdc.canvas.client.ctx function.
<script>
function callback(msg) {
if (msg.status !== 200) {
alert("Error: " + msg.status);
return;
40
SAML Single Sign-On for Canvas AppsCanvas SDK
}
alert("Payload: ", msg.payload);
}
var ctxlink = Sfdc.canvas.byId("ctxlink");
var client = Sfdc.canvas.oauth.client();
ctxlink.onclick=function() {
Sfdc.canvas.client.ctx(callback, client)};
}
</script>
<a id="ctxlink" href="#">Get Context</a>
SEE ALSO:
Canvas SDK
Context
Filtering CanvasRequest Context Data
Cross-Domain XHR
Canvas apps are loaded on a Salesforce page in an iFrame. The Canvas app has its own domain and can't make XML HTTP request (XHR)
calls back to the *.salesforce.com domain. You can develop and deploy your own proxies as part of the SDK, however, Canvas provides
a client-side proxy written in JavaScript. This proxy enables client-side XHR calls back to Salesforce.
Important: To prepare your Canvas apps for the new web browser restrictions on third-party cookies, see How Third-Party Cookie
Restrictions Impact Salesforce Canvas Apps in Salesforce Help.
If you use this proxy from the client to make an XHR request, the API forwards the request to the outer iFrame and the request is submitted
on your behalf. When the request is complete, the SDK calls the clients callback function with the results. Here are some examples of
how you can make XHR calls:
Getting a List of Chatter Users on page 41
Posting to a Chatter Feed on page 42
Note: The SDK supports cross-domain XHR calls, however, it shouldnt be used to make same-domain calls.
Getting a List of Chatter Users
Posting to a Chatter Feed
SEE ALSO:
Canvas SDK
Getting a List of Chatter Users
The following code example shows a call to return a list of Chatter users.
// Paste the signed request string into a JavaScript object for easy access.
41
Cross-Domain XHRCanvas SDK
var sr = JSON.parse('<%=signedRequestJson%>');
// Reference the Chatter user's URL from Context.Links object.
var chatterUsersUrl = sr.context.links.chatterUsersUrl;
// Make an XHR call back to salesforce through the supplied browser proxy.
Sfdc.canvas.client.ajax(chatterUsersUrl,
{client : sr.client,
success : function(data){
// Make sure the status code is OK.
if (data.status === 200) {
// Alert with how many Chatter users were returned.
alert("Got back " + data.payload.users.length +
" users"); // Returned 2 users
}
}});
SEE ALSO:
Cross-Domain XHR
Context
Links
Posting to a Chatter Feed
The following code example shows a call to post an item to the context users Chatter feed.
var sr = JSON.parse('<%=signedRequestJson%>');
// Reference the Chatter user's URL from Context.Links object.
var url = sr.context.links.chatterFeedsUrl+"/news/"+sr.context.user.userId+"/feed-items";
var body = {body : {messageSegments : [{type: "Text", text: "Some Chatter Post"}]}};
Sfdc.canvas.client.ajax(url,
{client : sr.client,
method: 'POST',
contentType: "application/json",
data: JSON.stringify(body),
success : function(data) {
if (201 === data.status) {
alert("Success");
}
}
});
SEE ALSO:
Cross-Domain XHR
Context
Links
42
Posting to a Chatter FeedCanvas SDK
Alternatives to Cookies for User Tracking
When creating websites and applications, the HTML <iframe> element lets you display third-party content within the current page
window. As modern browsers have increased privacy for end users, the iframe structure is becoming more scrutinized and restricted.
Third-party applications exposed as Canvas apps are surfaced in the Salesforce user interface via an iframe. To avoid problems loading
your Canvas apps in Salesforce, design applications that dont rely on cookies, session storage, or local storage to track users.
Cookies and other storage have traditionally been reliable ways to add application state on top of the state-less HTTP protocol. However,
cookies and storage also allow applications to track users in ways that users dont suspect. Modern browsers are working to enhance
privacy and security on the web. Applications written years ago may not behave the same way in modern browsers or when used in
iframe containers by applications, such as Salesforce. In the past, content hosted in an iframe would access its own storage, as if it was
hosted in a first-party context. Browsers now treat content hosted in an iframe as third-party applications.
Third-party applications exposed as Canvas apps work outside of Salesforce, but when exposed in Salesforce via an iframe, the content
may not load properly because the content is served from a different domain. Browsers place tracking and user-privacy restrictions on
these applications when theyre used in Salesforce. For example:
Cookies are not sent in page requests and XHRs.
Session storage and local storage access are denied.
JavaScript APIs, such as alert() and confirm(), are blocked.
To avoid problems late in development, test Canvas apps in a Salesforce container early. To design applications that dont rely on cookies,
session storage, or local storage to track users, build your Canvas apps as single-page applications (SPAs).
Warning: One side effect of not using cookies or storage is that you may not be logged into your application in multiple tabs. If
SPAs dont work for your development scenarios, ask your users to temporarily allow tracking for the browser where your Canvas
app is used. Modifying settings in your web browser typically affects all websites, not just Salesforce. In Chrome and Firefox, you
may add specific domains to always allow cookies, and can instruct your users to do the same. See this list of Salesforces standard
domains, and add any third-party applications domains.
Use the Signed Request for Authentication
SPAs work with Canvas and iframes. These applications dont use page-level navigation after their first page load. Instead, they dynamically
rewrite the page as the user interacts, which means that the same JavaScript execution context is kept for the lifetime of the app. To
authorize users within your application, use the CanvasRequest object. After the first request, store the authorization token for
your app in JavaScript instead of in cookies or local storage. Authorize HTTPS requests using authorization headers through the fetch()
or XMLHttpRequest standard web APIs.
See Signed Request Authentication for details on the CanvasRequest object.
Single-page applications can also request temporary access to cookies and other tracking data using the Storage Access API. This API
relies on explicit user interaction to allow access to cookies. Access is granted until the application navigates, which is why a single-page
application is preferred over multi-page applications.
Note: The storage access API is not available in all browsers, and behaves differently in each browser. See Storage Access API for
details.
Stay Up-to-Date with Browser Changes
Different browsers behave differently and are actively changing their behaviors as privacy on the web evolves. Refer to each browsers
guidelines for the most up-to-date information.
Apple Safari
43
Alternatives to Cookies for User TrackingCanvas SDK
Microsoft Edge
Mozilla Firefox
Google Chrome
SEE ALSO:
Salesforce Developers Blog: Prepare for the Google Chrome Privacy Sandbox Initiative
Knowledge Article: Understand How Google's Privacy Sandbox Initiative Impacts Salesforce
Resizing a Canvas App
Canvas provides methods for resizing a canvas app. Full reference documentation for these methods can be found in the SDK and here.
autogrowStarts or stops a timer that checks the content size of the canvas iFrame and adjusts the frame. See Automatically
Resizing a Canvas App.
resizeInforms the parent window to resize the canvas iFrame. See Explicitly Resizing a Canvas App.
sizeReturns the current size of the canvas iFrame. See Getting the Size of a Canvas App.
subscribeSubscribes to parent events. Currently, canvas.scroll (of the parent) is the only supported parent event in
the canvas namespace. See Subscribing to Parent Events.
Attention: For resize functions to work with your canvas app, you must declare a DOCTYPE at the top of any HTML pages that
are associated with the app. For example: <!DOCTYPE html>.
Automatically Resizing a Canvas App
Explicitly Resizing a Canvas App
Getting the Size of a Canvas App
Subscribing to Parent Events
Handling Orientation Changes in Your Canvas App
SEE ALSO:
Canvas SDK
Automatically Resizing a Canvas App
The following code examples show how to call the autogrow method to resize a canvas app. Use this method when your content
will change size, but youre not sure when.
Note: In Mozilla
®
Firefox
®
and Microsoft
®
Internet Explorer
®
, the autogrow method might not resize the frame if the content
size is reduced. In this case, you can use the resize method to specify the exact size that you want to change the frame to.
// Turn on auto grow with default settings.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.autogrow(sr.client);
});
44
Resizing a Canvas AppCanvas SDK
// Turn on auto grow with polling interval of 100ms (milliseconds).
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.autogrow(sr.client, true, 100);
});
// Turn off auto grow.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.autogrow(sr.client, false);
});
SEE ALSO:
Resizing a Canvas App
Explicitly Resizing a Canvas App
Explicitly Resizing a Canvas App
The following code example shows how to call the resize method to resize a canvas app. If you dont specify the height and width
parameters, the parent window attempts to determine the height of the canvas app based on its content and then set the iFrame width
and height accordingly.
// Automatically determine the size.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.resize(sr.client);
});
// Set the height and width explicitly.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.resize(sr.client, {height : "1000px", width : "900px"});
});
// Set only the height.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.resize(sr.client, {height : "1000px"});
});
SEE ALSO:
Resizing a Canvas App
Automatically Resizing a Canvas App
Getting the Size of a Canvas App
45
Explicitly Resizing a Canvas AppCanvas SDK
Getting the Size of a Canvas App
The following code example shows how to call the size method to get the size of the canvas app. The console.log function
outputs the frame sizes so you can see the sizes change as you resize the canvas app.
// Get the canvas app sizes in the sizes object.
var sizes = Sfdc.canvas.client.size();
console.log("contentHeight; " + sizes.heights.contentHeight);
console.log("pageHeight; " + sizes.heights.pageHeight);
console.log("scrollTop; " + sizes.heights.scrollTop);
console.log("contentWidth; " + sizes.widths.contentWidth);
console.log("pageWidth; " + sizes.widths.pageWidth);
console.log("scrollLeft; " + sizes.widths.scrollLeft);
// Resize the canvas app.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.autogrow(sr.client);
});
SEE ALSO:
Resizing a Canvas App
Subscribing to Parent Events
Subscribing to Parent Events
The following code example shows how to call the subscribe method so that a canvas app can subscribe to parent events. This
example handles the onscroll event that fires when the user scrolls in the parent window.
//Subscribe to the parent window onscroll event.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
// Capture the onScrolling event of the parent window
Sfdc.canvas.client.subscribe(sr.client,
{name : 'canvas.scroll', onData : function (event) {
console.log("Parent's contentHeight; " + event.heights.contentHeight);
console.log("Parent's pageHeight; " + event.heights.pageHeight);
console.log("Parent's scrollTop; " + event.heights.scrollTop);
console.log("Parent's contentWidth; " + event.widths.contentWidth);
console.log("Parent's pageWidth; " + event.widths.pageWidth);
console.log("Parent's scrollLeft; " + event.widths.scrollLeft);
}}
);
});
SEE ALSO:
Resizing a Canvas App
46
Getting the Size of a Canvas AppCanvas SDK
Handling Orientation Changes in Your Canvas App
The orientation event enables you to handle changes in orientation when your canvas app appears on a mobile device. After
your canvas app subscribes to the event, the event fires whenever the parent window fires a window.orientation event. The
event returns a payload that contains these values.
DescriptionValue
The height of the app in pixels, specific to the device on
which the canvas app renders
clientHeight
The width of the canvas app in pixels, specific to the device
on which the canvas app renders
clientWidth
Contains one of these values.orientation
0: landscape to portrait
90: portrait to landscape
-90: portrait to landscape turned counterclockwise
The following code example shows how to subscribe to the orientation event.
// Capture the orientation event of the parent window.
Sfdc.canvas.client.subscribe(sr.client,
{name : 'canvas.orientation',
onData : function (event) {
console.log("Parent's orientation: " + event.orientation +
"Canvas app height: " + event.clientHeight +
"Canvas app width: " + event. clientWidth);
}} );
});
Note: The orientation event isnt supported on Windows phones.
SEE ALSO:
Resizing a Canvas App
Subscribing to Parent Events
Implementing Canvas App Events
Events provide a JavaScript-based way to send and receive events between canvas apps. Use events to enable communication between
multiple canvas apps on a single page.
One scenario might be a page on which you expose two custom apps as canvas apps: a travel and expense app, and an approvals app.
You can create an event so that when the status of an expense report changes, that event gets raised and contains data (in JSON format)
about that expense report. The approvals canvas app subscribes to that event and specifies a function thats called when the event is
raised. When the status is changed, the approvals app receives the event and the specified function runs.
Canvas provides methods for implementing custom events in a canvas app. Full reference documentation for these methods can be
found in the SDK and here.
47
Handling Orientation Changes in Your Canvas AppCanvas SDK
publishCreates a custom event to which other canvas apps or Visualforce pages can subscribe. See Creating a Canvas App
Event.
subscribeSubscribes to a parent event or custom event. This method can be used to subscribe to multiple events. See
Subscribing to a Canvas App Event.
unsubscribeUnsubscribe from a parent event or custom event. This method can be used to unsubscribe from multiple events.
See Unsubscribing from a Canvas App Event.
Note: The subscribe and unsubscribe methods can also be used to subscribe to a single Streaming API event.
Canvas App Events Considerations
Creating a Canvas App Event
Subscribing to a Canvas App Event
Unsubscribing from a Canvas App Event
SEE ALSO:
Canvas SDK
Canvas App Events Considerations
Using Streaming API in a Canvas App
Canvas App Events Considerations
Keep these considerations in mind when implementing canvas app events:
We recommend that you use a namespace when naming events, but its not required.
The event namespace is different than the organization namespace in Salesforce. However, if you use namespaces, we recommend
that you make the event namespace the same as the organization namespace.
The namespace must be a string with no periods in it. For example, my.name.space.statusChanged is invalid. An example
of a valid event name with a namespace is mynamespace.statusChanged.
These names are reserved and cant be used as a namespace:
canvas
chatter
force
publisher
salesforce
sfdc
Events work only between canvas apps on the same page. If you have a canvas app on the Chatter tab, that app cant subscribe to
events published by a canvas app on a Visualforce page.
You can subscribe to more than one custom event in a subscribe call.
You can subscribe to only one Streaming API event in a subscribe call.
You cant subscribe to a custom event and a Streaming API event with the same subscribe call.
48
Canvas App Events ConsiderationsCanvas SDK
If you define multiple events with the same name in an array, only the last event defined is available. In this example, the last event
where the Status is Negotiating is the one thats used.
Sfdc.canvas.client.subscribe(sr.client, [
{
name :"mynamespace.statusChanged",
payload : {status : 'Closed'}
},
{
name:"mynamespace.statusChanged",
payload : {status : 'Negotiating'}
]);
This is also true for Streaming API events.
SEE ALSO:
Implementing Canvas App Events
Creating a Canvas App Event
The following code example shows how to call the publish method to create a canvas app event. If youre using a namespace, the
event name must be prefaced by the namespace. For example, namespace.eventName.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.publish(sr.client,
{name : "mynamespace.statusChanged", payload : {status : 'Completed'}});
});
SEE ALSO:
Implementing Canvas App Events
Creating a Canvas App Event
Subscribing to a Canvas App Event
Subscribing to a Custom Event
The following code example shows how to call the subscribe method to subscribe to a canvas app event.
// Subscribe to a custom event.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.subscribe(sr.client,
{name : 'mynamespace.statusChanged', onData : function (event) {
console.log("Subscribed to custom event ", event);
}}
);
});
49
Creating a Canvas App EventCanvas SDK
Subscribing to Multiple Custom Events
The following code example shows how to call the subscribe method to subscribe to multiple canvas app events. The events you
subscribe to can be in different namespaces or might not have a namespace. When a canvas app subscribes to an event, it creates an
association between an event (in the other canvas app) and a function (in the subscribing canvas app).
// Subscribe to multiple events.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.subscribe(sr.client, [
{name : 'mynamespace.statusChanged', onData : handler1},
{name : 'anothernamespace.tripCancelled', onData : handler2},
]);
});
Using the travel and expense and approval canvas app examples, your approvals canvas app has two functions: handler1 and
handler2. That canvas app then subscribes to two events in the travel and expense canvas app: mynamespace.statusChanged
and mynamespace.tripCancelled. When the mynamespace.statusChanged event is received by the approvals app,
function handler1 is called. When the anothernamespace.tripCancelled event is received by the approvals app,
function handler2 is called.
SEE ALSO:
Implementing Canvas App Events
Subscribing to Parent Events
Unsubscribing from a Canvas App Event
Unsubscribing from a Canvas App Event
Unsubscribing from a Custom Event
The following code example shows how to call the unsubscribe method to unsubscribe from a canvas app event.
// Unsubscribe from a custom event.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.unsubscribe(sr.client, {name : "mynamespace.statusChanged"});
});
Unsubscribing from Multiple Custom Events
The following code example shows how to call the unsubscribe method to unsubscribe from multiple canvas app events. The
events you subscribe to can be in different namespaces or might not have a namespace.
// Unsubscribe from multiple events.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.unsubscribe(sr.client, ['mynamespace.statusChanged',
50
Unsubscribing from a Canvas App EventCanvas SDK
"anothernamespace.tripCancelled"]);
});
SEE ALSO:
Implementing Canvas App Events
Subscribing to a Canvas App Event
Subscribing to Parent Events
Using Streaming API in a Canvas App
Canvas provides an event and methods that enable canvas apps to listen for Streaming API notifications.
sfdc.streamingapiJavaScript event that you create and associate with a Streaming API channel defined by a PushTopic.
See Using the Streaming API Event.
subscribeSubscribes to the sfdc.streamingapi event that you define. See Subscribing to a Streaming API Event.
unsubscribeUnsubscribes from the sfdc.streamingapi event. See Unsubscribing from a Streaming API Event.
Using the Streaming API Event
Subscribing to a Streaming API Event
Unsubscribing from a Streaming API Event
SEE ALSO:
Using the Streaming API Event
Subscribing to a Streaming API Event
Unsubscribing from a Streaming API Event
Streaming API Developer's Guide
Using the Streaming API Event
The Canvas SDK contains an event called sfdc.streamingapi that lets you define an event in your canvas app and associate that
event with a Streaming API channel. You then use the subscribe method to subscribe to the event and receive Streaming API
notifications.
For example, in Salesforce, you can create a Streaming API channel that receives notifications when an InvoiceStatement is updated and
the Status changes to Closed. In your canvas app, you can then create an event associated with that channel and subscribe to it. In
Salesforce, whenever an invoice statement is closed, the activated canvas app receives the notification and can perform an action such
as displaying a message to the user.
Here are some considerations when defining the Streaming API event:
The event takes a single parameter that contains the PushTopic name.
51
Using Streaming API in a Canvas AppCanvas SDK
The PushTopic name must be prefaced by /topic/.
{name:"sfdc.streamingapi", params:{topic:"/topic/myPushTopicName"}}
SEE ALSO:
Using Streaming API in a Canvas App
Subscribing to a Streaming API Event
Subscribing to a Streaming API Event
This code example shows how to call the subscribe method so that a canvas app can subscribe to a Streaming API event. When
you subscribe to an event, you call the standard sfdc.canvas.client.subscribe method that you use to subscribe to a
canvas app event. When you call the subscribe method, you must pass in the client and the Streaming API event. Only canvas apps
that are open and subscribed to the event can receive Streaming API notifications.
In this example, the onComplete method specifies the function that runs after the code successfully subscribes to the event. The
onData method specifies the function that runs when a Streaming API notification is received by the event.
// Subscribe to Streaming API events.
// The PushTopic to subscribe to must be passed in.
// The 'onComplete' method may be defined,
// and will fire when the subscription is complete.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
var handler1 = function(){ console.log("onData done");},
handler2 = function(){ console.log("onComplete done");};
Sfdc.canvas.client.subscribe(sr.client,
{name : 'sfdc.streamingapi', params:{topic:"/topic/InvoiceStatements"}},
onData : handler1, onComplete : handler2}
);
});
When you call the subscribe method, a REST call is made to ensure that the canvas app has the OAuth scope needed to connect
to the Streaming API. Therefore, each time a canvas app subscribes to a Streaming API event, one API call is used and is counted against
the organizations total API requests limits. The canvas app needs at least the Access and Manage Your Data (API) OAuth scope to
connect to the Streaming API.
If the call to the subscribe method is successful, the onComplete method is called with a payload of
{success:true,handle:handle}. The handle is an array that contains the name of the Streaming API channel being
subscribed to and the subscriptionId is an integer that contains a unique ID. For example,
["/topics/InvoiceStatements", subscriptionId]. If the call to the subscribe method fails, the onComplete
method is called with a payload of {success:false,errorMessage:msg}. The msg is a string that contains the cause of
the error.
To receive Streaming API notifications, you must create a channel defined by a PushTopic. For more information, see Step 2: Create a
PushTopic in the Streaming API Developer Guide.
SEE ALSO:
Using the Streaming API Event
Unsubscribing from a Streaming API Event
52
Subscribing to a Streaming API EventCanvas SDK
Unsubscribing from a Streaming API Event
This code example shows how to call the unsubscribe method so that a canvas app can unsubscribe from a Streaming API event.
//Unsubscribe from Streaming API events.
//The PushTopic to unsubscribe from must be passed in.
Sfdc.canvas(function() {
sr = JSON.parse('<%=signedRequestJson%>');
Sfdc.canvas.client.unsubscribe(sr.client, {name : 'sfdc.streamingapi',
params:{topic:"/topic/InvoiceStatements"}});
});
SEE ALSO:
Using the Streaming API Event
Subscribing to a Streaming API Event
Debugging in a Canvas App
You must use Chrome, Firefox, or Safari to follow these steps.
When using the Canvas SDK, you can enable debug mode to make troubleshooting easier.
1. With your canvas app open in your browser, open the console.
2. Type Sfdc.canvas.console.enable(); and press return.
3. Refresh your browser.
Use data from this screen to debug canvas-related problems.
Using the <select> Tag in a Canvas App
If you use HTML <select> tags in your canvas web application and intend to make your canvas app available in the Salesforce
mobile app, keep in mind that behavior can be unpredictable on some devices. Consider using a jQuery or CSS alternative to using
<select>.
53
Unsubscribing from a Streaming API EventCanvas SDK
CHAPTER 5 Canvas Apps and Visualforce Pages
In addition to standard canvas apps, Canvas also lets you expose a canvas app on a Visualforce page.
This means you can display a canvas app anywhere you can display a Visualforce page.
In this chapter ...
Visualforce Page
Code Examples
Developers can use Visualforce pages to:
Override standard buttons, such as the New button for accounts, or the Save button for contacts
Visualforce
Considerations
Override tab overview pages, such as the Accounts tab home page
apex:canvasApp
Component
Define custom tabs
Embed components in detail page layouts
Using Events
between a
Create dashboard components or custom help pages
Customize, extend, or integrate the sidebars in the Salesforce Console (custom console components)
Visualforce Page and
a Canvas App
To host a canvas app on a Visualforce page, use the <apex:canvasApp> component.
Note: The Canvas framework includes methods that you can use to circumvent the navigational
limitations of the iframe that contains a canvas app, without using Visualforce pages. These methods
offer a streamlined alternative for controlling navigation to or from canvas apps in the Salesforce
app. For details, see Salesforce Mobile App Navigation Methods for Use with Canvas Apps on page
80.
SEE ALSO:
Visualforce Page Code Examples
Visualforce Considerations
apex:canvasApp Component
54
Visualforce Page Code Examples
You can display a canvas app on a Visualforce page in a number of ways.
These examples show the different ways to reference the canvas app using applicationName, developerName, and
namespacePrefix.
Object Detail Page
The following code snippet is an example of how to display a canvas app on an Account page. The code specifies the size of the canvas
app to be 400 pixels high and 750 pixels wide. This examples specifies the canvas app using the applicationName and
namespacePrefix.
<apex:page standardController="Account">
<apex:canvasApp applicationName="Test Inline Visualforce"
namespacePrefix="testorg"
height="400px" width="750px"/>
</apex:page>
Standard Page
The following code snippet is an example of how to display a canvas app on a Visualforce page. The code specifies the size of the canvas
app to be 1,000 pixels high and 800 pixels wide. In addition, the code passes three custom parameters to the canvas app. This examples
specifies the canvas app using the developerName and namespacePrefix.
<apex:page>
<apex:canvasApp developerName="Test_Standard_Visualforce"
namespacePrefix="testorg" height="1000px" width="800px"
parameters='{"p1":"value1", "p2":"value2", "p3":"value3"}'/>
</apex:page>
Standard Page with a Border and Scrolling
The following code snippet is an example of how to display a canvas app with some additional UI enhancements on a Visualforce page.
The code specifies the size of the canvas app to be 100 pixels high and 500 pixels wide. In addition, the code specifies that there should
be a border of 2 pixels around the canvas app and that scrolling should be enabled. This examples specifies the canvas app using only
the applicationName (this is only valid in the organization in which the canvas app was created, and if that organization doesnt
have a namespacePrefix.
<apex:page>
<apex:canvasApp applicationName="Test Scrolling Visualforce"
height="100px" width="500px"
border="2" scrolling="yes"/>
55
Visualforce Page Code ExamplesCanvas Apps and Visualforce Pages
</apex:page>
SEE ALSO:
Canvas Apps and Visualforce Pages
Visualforce Considerations
Visualforce Developer's Guide
apex:canvasApp Component
Visualforce Considerations
Keep the following considerations in mind when using the <apex:canvasApp> component:
The <apex:canvasApp> component is available only in organizations that have Canvas enabled and in Visualforce pages at
version 27.0 or higher.
If you include a canvas app on an object detail layout, you must provide the height of the canvas app in the page layout as well as
in the <apex:canvasApp> component.
LocationIf the canvas app is in a Visualforce page, then the Environment.displayLocation field contains the value
Visualforce.
SEE ALSO:
Canvas Apps and Visualforce Pages
apex:canvasApp Component
apex:canvasApp Component
Use this component to display a canvas app on a Visualforce page. The table below lists the component attributes.
Pass parameters that contain non-alphanumeric characters such as quotation marks, apostrophes, and so on, as JavaScript-safe objects.
To do this, write an Apex class that uses the methods of the Apex JSONGenerator class to build the JSON string. Call the Apex class from
the parameters value:
<apex:page controller="JSONGeneratorSample">
<apex:canvasApp developerName="mycanvas" parameters="{!generateJSON}" />
</apex:page>
Alternatively, you can also use the JSENCODE function to escape the strings:
<apex:page standardController="Account">
<apex:canvasApp developerName="mycanvas" parameters="{!JSENCODE(Account.Description)}"
/>
</apex:page>
DescriptionTypeAttribute
Name of the canvas app. Either applicationName or
developerName is required.
StringapplicationName
56
Visualforce ConsiderationsCanvas Apps and Visualforce Pages
DescriptionTypeAttribute
Width of the canvas app border, in pixels. If not specified, defaults
to 0 pixels.
Stringborder
Unique ID of the canvas app window. Use this attribute when
targeting events to the canvas app.
StringcanvasId
ID of the HTML element in which the canvas app is rendered. If not
specified, defaults to null. The container specified by this attribute
StringcontainerId
cant appear after the <apex:canvasApp> component. These
code examples show valid usage of the <div> container and the
containerId attribute:
<apex:page>
<div id="container1"></div>
<apex:canvasApp applicationName="myApp"
containerId="container1"/>
</apex:page>
<apex:page>
<div id="container1">
<apex:canvasApp
applicationName="myApp"
containerId="container1"/>
</div>
</apex:page>
This code example shows invalid usage of the <div> container
and the containerId attribute:
<apex:page>
<apex:canvasApp applicationName="myApp"
containerId="container1"/>
<div id="container1">
</div>
</apex:page>
Internal name of the canvas app. You specify this value in the API
Name field when you expose the canvas app by creating a
StringdeveloperName
connected app. Either developerName or
applicationName is required.
Specifies the fields returned in the signed request Record object
when the component appears on a Visualforce page placed on an
StringentityFields
object. If this attribute isnt specified or is blank, then only the Id field
is returned. Valid attribute values include:
Comma-separated list of field names. For example, to return the
Account Phone and Fax fields, the attribute would look like:
entityFields="Phone,Fax"
Asterisk * to return all fields from the associated object.
57
apex:canvasApp ComponentCanvas Apps and Visualforce Pages
DescriptionTypeAttribute
Canvas app window height, in pixels. If not specified, defaults to 900
pixels.
Stringheight
Unique identifier that allows the <apex:canvasApp>
component to be referenced by other components on the page.
Stringid
The maximum height of the Canvas app window in pixels. Defaults
to 2000 px; 'infinite' is also a valid value.
StringmaxHeight
The maximum width of the Canvas app window in pixels. Defaults
to 1000 px; 'infinite' is also a valid value.
StringmaxWidth
Namespace value of the Developer Edition organization in which
the canvas app was created. You can set a namespace only in a
StringnamespacePrefix
Developer Edition organization, so this is optional if the canvas app
was created in a different type of organization. If not specified,
defaults to null.
Name of the JavaScript function to be called if the canvas app fails
to render.
StringonCanvasAppError
Name of the JavaScript function to be called after the canvas app
loads.
StringonCanvasAppLoad
Object representation of parameters passed to the canvas app.
Supply in JSON format or as an expression to a JavaScript JSON object
literal. If not specified, defaults to null.
Stringparameters
Specifies whether the component is rendered on the page. If not
specified, defaults to true.
Booleanrendered
Specifies whether the canvas app window uses scroll bars. Valid
values are:
Stringscrolling
auto
no
yes
If not specified, defaults to no. If this attribute contains an invalid
value, its treated the same as no to prevent browser errors.
Canvas app window width, in pixels. If not specified, defaults to 800
pixels.
Stringwidth
58
apex:canvasApp ComponentCanvas Apps and Visualforce Pages
Returning Fields in the Record Object
When you use the <apex:canvasApp> component to display a canvas app on a Visualforce page, and that page is associated
with an object (placed on the page layout, for example), you can specify fields to be returned from the related object. To do this,
use the entityFields attribute. You can use this attribute in one of the following ways.
SEE ALSO:
Canvas Apps and Visualforce Pages
Visualforce Developer's Guide
Visualforce Page Code Examples
Returning Fields in the Record Object
Returning Fields in the Record Object
When you use the <apex:canvasApp> component to display a canvas app on a Visualforce page, and that page is associated with
an object (placed on the page layout, for example), you can specify fields to be returned from the related object. To do this, use the
entityFields attribute. You can use this attribute in one of the following ways.
Return Specific Object Fields
You can return specific object fields in the Record object by setting the entityFields attribute to a comma-separated list of field
names. If theres an invalid field name in the list, then that field name is ignored and the valid fields are returned in the Record object.
<apex:canvasApp applicationName="MyApp" entityFields="Phone,Fax,BillingCity"
containerId="canvasAppDiv"/>
returns a Record object that looks like this:
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
}
Return All Object Fields
You can return all object fields in the Record object by setting the entityFields attribute to the wildcard "*".
<apex:canvasApp applicationName="MyApp" entityFields="*" containerId="canvasAppDiv"/>
returns a Record object that looks like this:
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
59
Returning Fields in the Record ObjectCanvas Apps and Visualforce Pages
"Id":"001xx000003DGWiAAO",
"IsDeleted":false,
"MasterRecordId":null,
"Name":"Edge Communications",
"Type":"Customer - Channel",
"ParentId":null,
"BillingStreet":"123 Main Street",
"BillingCity":"Seattle",
"BillingState":"WA",
"BillingPostalCode":"98121",
"BillingCountry":"USA",
...
}
Return the Id Field
If the <apex:canvasApp> component doesnt have the entityFields attribute or if the attribute is blank, then only the Id
field is returned in the Record object.
<apex:canvasApp applicationName="MyApp" containerId="canvasAppDiv"/>
returns a Record object that looks like this:
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO"
}
SEE ALSO:
apex:canvasApp Component
Record
Controlling Canvas App Behavior
Using Events between a Visualforce Page and a Canvas App
Canvas provides methods that you can use to publish and subscribe to events between your canvas app and the parent Visualforce
page. This process includes publishing events from your Visualforce page, listening for events on your Visualforce page, unsubscribing
from events on your Visualforce page, and resizing the Visualforce page that contains the canvas app. This process for resizing a canvas
app differs from the process where the canvas app resizes itself, which is described in Resizing a Canvas App. Full reference documentation
for these methods can be found in the SDK and here.
publishPublishes an event from the Visualforce page that the canvas app can subscribe to. See Publishing a Canvas Event
from a Visualforce Page.
resizeUsed by a Visualforce page to resize a canvas app iFrame. See Resizing a Canvas App in a Visualforce Page.
subscribeUsed by a Visualforce page to subscribe to events that the canvas app might publish. See Subscribing to Events.
unsubscribeUsed by a Visualforce page to unsubscribe to parent events that the canvas app might publish. See Unsubscribing
from Events in a Visualforce Page.
60
Using Events between a Visualforce Page and a Canvas AppCanvas Apps and Visualforce Pages
The Controller.js object is needed for the Visualforce page to use these methods. Your script in the Visualforce page might look something
like this:
<script
type="text/javascript"src="https://yourDomain.my.salesforce.com/canvas/sdk/js/30.0/controller.js">
Note: You can use Lightning Platform methods to smoothly integrate navigation between a canvas app and the Salesforce mobile
app, without using Visualforce. The methods are events that reside in the JavaScript library within the Canvas framework. When
you call one of the navigation methods from your canvas code, you send an event into Salesforce that reads the payload and
directs the user to the specified destination. For more information, see Salesforce Mobile App Navigation Methods for Use with
Canvas Apps on page 80.
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
Subscribing to Events
Unsubscribing from Events in a Visualforce Page
SEE ALSO:
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
Subscribing to Events
Unsubscribing from Events in a Visualforce Page
apex:canvasApp Component
Publishing a Canvas Event from a Visualforce Page
The following code example shows how to call the publish method to publish the myevent event from a Visualforce page. Any
canvas app that subscribes to this event will receive the event.
// Target all canvas apps.
Sfdc.canvas.controller.publish({name : 'mynamespace.myevent',
payload : {}});
The following code example shows how to call the publish method to publish an event to a specified canvas app from the Visualforce
page.
If an event is published to specific canvas apps, even if other canvas apps on a Visualforce page are subscribed to it, only the canvas apps
specified will receive that event. Using this code example, if the Visualforce page contained canvas apps app1, app2, and app3, and they
all subscribed to myevent, only app1 would receive the event.
// Target a specific canvas app
// where "app1" is the canvasId specified in the canvas component.
// For example: <apex:canvasApp canvasId="app1">
Sfdc.canvas.controller.publish({name : 'mynamespace.myevent',
payload : {},
target : {canvas : 'app1'}});
61
Publishing a Canvas Event from a Visualforce PageCanvas Apps and Visualforce Pages
In the target parameter, you can specify multiple canvas apps by passing in an array of canvas apps: target : [{canvas :
'app1'}, {canvas: 'app2'}].
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Resizing a Canvas App in a Visualforce Page
Subscribing to Events
Unsubscribing from Events in a Visualforce Page
apex:canvasApp Component
Resizing a Canvas App in a Visualforce Page
The following code example shows how to call the resize method to explicitly set the height and width on a specific canvas app
within a Visualforce page.
// Set the height and width explicitly and target a canvas app
// Where 'mycanvas0' is the canvasId on the canvas component
// <apex:canvasApp canvasId="mycanvas0"/>
var target = {canvas : "mycanvas0"};
Sfdc.canvas.controller.resize( {height : "1000px", width : "900px"}, target);
The following code example shows how to call the resize method to set the height on all canvas apps within a Visualforce page.
//Set only the height on all canvas apps
Sfdc.canvas.controller.resize( {height : "1000px"});
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Publishing a Canvas Event from a Visualforce Page
Subscribing to Events
Unsubscribing from Events in a Visualforce Page
Subscribing to Events
The following code example shows how to call the subscribe method within a Visualforce page to subscribe to specified events
published from a canvas app.
// Subscribe to a single event.
Sfdc.canvas.controller.subscribe({name : 'mynamespace.myevent0',
onData : function (e) {}});
// Subscribe to multiple events in a single call.
Sfdc.canvas.controller.subscribe([
{name : 'mynamespace.myevent1', onData : function(e) {}},
62
Resizing a Canvas App in a Visualforce PageCanvas Apps and Visualforce Pages
{name : 'mynamespace.myevent2', onData : function(e) {}}
]);
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
Unsubscribing from Events in a Visualforce Page
Implementing Canvas App Events
Unsubscribing from Events in a Visualforce Page
The following code example shows how to call the unsubscribe method within a Visualforce page to unsubscribe from two events.
Sfdc.canvas.controller.unsubscribe(['mynamespace.myevent2', 'mynamespace.myevent2']);
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
Publishing a Canvas Event from a Visualforce Page
Resizing a Canvas App in a Visualforce Page
Subscribing to Events
63
Unsubscribing from Events in a Visualforce PageCanvas Apps and Visualforce Pages
CHAPTER 6 Lightning Component Code Examples
The following examples show how to reference a <force:canvasApp> component using
applicationName, developerName, and namespacePrefix.
Note: When possible, use developerName instead of applicationName. The
developerName (also called the API name) is the permanent name assigned to a Connected
App when you create a canvas app. You can change the applicationName, which can break
Aura components that use an outdated name.
Object Detail Page
This example displays a canvas app on an Account page using the applicationName and
namespacePrefix attributes of <force:canvasApp>.
In myCanvasApp.cmp, we first define an Aura attribute called canvasParameters. We use this
attribute to pass a recordId into the canvas app. Next, we define an init handler, which invokes
the action method doInit when the component is initialized. In <force:canvasApp>, we set
the size of the canvas app in pixels.
<!-- myCanvasApp.cmp file -->
<aura:component implements="flexipage:availableForAllPageTypes,
force:hasRecordId">
<aura:attribute name="canvasParameters" type="string" />
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<force:canvasApp applicationName="Test Inline Aura"
namespacePrefix="testorg"
height="400px" width="750px"
parameters="{!v.canvasParameters}"/>
</aura:component>
In myCanvasAppController.js, the doInit method sets the recordId in the
canvasParameters attribute.
// myCanvasAppController.js
({
doInit : function(cmp, evt, helper) {
var recordId = cmp.get("v.recordId");
cmp.set("v.canvasParameters", JSON.stringify({
recordId: recordId
}));
64
}
})
Standard Page
This example displays a canvas app in an Aura component using the developerName and
namespacePrefix attributes of <apex:canvasApp>. The code specifies the size of the canvas
app to be 1000 pixels high and 800 pixels wide. It passes three custom parameters to the canvas app.
<aura:component>
<force:canvasApp developerName="Test_Standard_Aura"
namespacePrefix="testorg" height="1000px" width="800px"
parameters='{"p1":"value1", "p2":"value2", "p3":"value3"}'/>
</aura:component>
65
Lightning Component Code Examples
CHAPTER 7 Canvas Apps in a Page Layout or a Mobile Card
You can add a canvas app to a page layout for any standard or custom object. For the Canvas Apps
category to appear in the palette when you edit a page layout, you must set the canvas app location to
Layouts and Mobile Cards when you create the canvas app in the Salesforce application.
SEE ALSO:
Add a Canvas App to a Page Layout
Where Canvas Apps Appear in a Page Layout
In this chapter ...
Where Canvas Apps
Appear in a Page
Layout
Add a Canvas App to
a Page Layout
66
Where Canvas Apps Appear in a Page Layout
Depending on where you place the canvas app on the page layout, the canvas app might appear in the full Salesforce site or in the
Salesforce mobile app.
This table describes where the canvas app appears when you add it to the page layout.
Where the canvas app appears in the
Salesforce mobile app
The canvas app
appears in the
Salesforce mobile
app?
The canvas app
appears in the full
Salesforce site?
If the canvas app is added
to the page layout in ...
Record detail pageYesYesAny section (other than the
Mobile Cards section)
Mobile cardYesNoMobile Cards section
SEE ALSO:
Canvas Apps in a Page Layout or a Mobile Card
Add a Canvas App to a Page Layout
Add a Canvas App to a Page Layout
Add a canvas app to the page layout for an Account.
1. To create a canvas app, follow the steps in Create the App.
2. From Setup, enter Apps in the Quick Find box, then select Manage Connected Apps.
3. In the Connected Apps list view, click Edit next to the app that you created.
4. In the Canvas Apps Settings section, in the Locations field, select Layouts and Mobile Cards.
5. Click Save.
6. From Setup, click Object Manager, then select Account.
7. On the Account object management page, click Page Layouts, then click Account Layout.
The Canvas Apps category is in the palette and the canvas app because you set the location of the canvas app to Layouts and Mobile
Cards.
8. Drag the canvas app element to where you want it to appear in the page layout, and then click Save.
If you add the canvas app to any section other than the Mobile Cards section, the canvas app appears in the page layout in the
full Salesforce site or in the record detail page in the Salesforce mobile app.
67
Where Canvas Apps Appear in a Page LayoutCanvas Apps in a Page Layout or a Mobile Card
If you add the canvas app to the Mobile Cards section, the canvas app appears only in the mobile card.
9. To see your changes, click the Accounts tab, and then click an account.
You can modify additional properties of the canvas app in the page layout by clicking the wrench icon .
Width (in pixels or %)The width of the canvas app; defaults to 100%. Changes to the width of the canvas app appear
in both the full Salesforce site and the Salesforce mobile app. However, canvas apps are displayed in a single-column layout, so we
recommend that you leave the width at 100%.
Height (in pixels)The height of the canvas app; defaults to 200 pixels. Changes to this field appear to the user for canvas
apps that appear in both the full Salesforce site and the Salesforce mobile app.
Show scrollbarsWhether scrollbars are displayed on the canvas app iFrame. Changes to this field render for canvas apps
that appear in the full Salesforce site but not for canvas apps that appear in the Salesforce mobile app.
Show labelWhether to display the page layout section label. Changes to this field appear to the user for canvas apps that
appear in both the full Salesforce site and in the Salesforce mobile app.
SEE ALSO:
Canvas Apps in a Page Layout or a Mobile Card
Where Canvas Apps Appear in a Page Layout
Salesforce Help: Find Object Management Settings
68
Add a Canvas App to a Page LayoutCanvas Apps in a Page Layout or a Mobile Card
CHAPTER 8 Canvas Apps in the Publisher
Canvas enables you to expose your canvas apps as quick actions. The publisher allows users access to
the most common actions in your organization. You can expand the publisher to include a canvas app
In this chapter ...
Set Canvas App
Location and Create
the Action
so that users can leverage the common custom actions of a canvas app. These actions can then integrate
with the feed and create a feed post specific to the action that was performed.
Developers can use canvas apps in the publisher to:
Create the Action
Manually
Add content from a Web application into the Chatter publisher.
Create a custom action that exposes a canvas app.
Canvas SDK
Publisher Events
Integrate your canvas app directly into the publisher life cycle: post from your canvas app into the
Chatter feed, use the Share button functionality, and designate where to post your message.
Publisher Context
Considerations
For example, you might have a canvas app that your users use to log their hours worked. You can create
a quick action that allows a user to open that canvas app in the publisher so they can quickly submit a
time record, all right from within the publisher.
Publisher Canvas
App Access
Considerations
Users can still access the canvas app in the standard way for full functionality; but the canvas app in the
publisher provides quick access to the most common functions of your app. A user can select the quick
action and create a Chatter feed item that can be a text post, a link post, or even a canvas post.
SEE ALSO:
Set Canvas App Location and Create the Action
Canvas Apps in the Chatter Feed
69
Set Canvas App Location and Create the Action
To add a canvas app to the publisher or action bar, you must set the location and create the action when you create the canvas app.
1. In Salesforce, from Setup, enter Apps in the Quick Find box, then select Apps.
2. In the Connected Apps related list, click New. Fill out the basic fields for your canvas app. See Create the Canvas App.
3. In the Canvas App settings, select Canvas and in the Locations field, select Publisher. You must select this location for your
canvas app to appear in both the publisher in the full Salesforce site and in the action bar in the Salesforce mobile app.
4. Select the Create Actions Automatically field. This creates a quick action for the canvas app.
5. To hide the publisher header, which contains the "What are you working on?" text, select Hide Publisher Header. This
hides the header in both the full Salesforce site and in the Salesforce mobile app.
6. To hide the publisher Share button from users in both the full Salesforce site and in the Salesforce mobile app, select Hide
Publisher Share Button. This checkbox is enabled only if Hide Publisher Header has been selected.
For the canvas app to appear as an action, you must add the action to the global publisher layout. See Customizing Global Publisher
Layouts in the Salesforce Help.
SEE ALSO:
Where Canvas Apps Appear
Create the Action Manually
Canvas Apps in the Publisher
Create the Action Manually
If you didnt select the Create Actions Automatically field when you created the canvas app, then youll need to create
the action manually.
1. From Setup, enter Actions in the Quick Find box, then select Global Actions
2. Click New Action.
3. In the Action Type field, select Custom Canvas.
4. In the Canvas App field, select the canvas app that you want to appear as an action.
Only canvas apps that have a location of Publisher will appear in this field.
5. In the Height field, enter the height of the canvas app in pixels.
This is the initial height of the canvas app when it appears in the publisher. You can use the Canvas SDK resize() method to
change the height up to a maximum of 500 pixels.
6. In the Label field, enter a value.
This value appears as the quick action title in the user interface.
7. In the Name field, enter a unique value with no spaces.
8. Optionally, in the Icon field, you can upload an icon by clicking Change Icon. You must upload the icon as a static resource before
you can change it here.
9. Click Save.
70
Set Canvas App Location and Create the ActionCanvas Apps in the Publisher
For the canvas app to appear as a quick action, you must add the action to the global layout. See Customizing Global Publisher Layouts
in the Salesforce Help.
SEE ALSO:
Set Canvas App Location and Create the Action
Publisher Context Considerations
Canvas SDK Publisher Events
When you expose a canvas app in the publisher, you can use well-defined events to enable communication between the canvas app
and the publisher.
Your canvas app can subscribe and publish these events to more tightly integrate with the publisher framework. For example, you can
activate the standard Chatter Share button to post a Chatter feed item. You can also access the post text that the user enters in the
What are you working on? field in the publisher and combine that with content from your app.
DescriptionField
Fired by the publisher when the canvas app is deactivated or hidden. This
can happen when the user selects a different application in the publisher or
publisher.clearPanelState
after the Share button has been clicked. A Visualforce page can also listen
for this event.
Fired by the publisher when an error condition is encountered such as when
invalid data has been submitted. For example:
publisher.failure
The text in the feed is too long
The canvas app youre attempting to publish to the feed doesnt exist
The canvas app URL is invalid
The canvas app should listen for this event and alert the user that an error
occurred and the post didnt get created.
Fired by the publisher when the Share button is clicked. The payload contains
information such as the text entered into the What are you working
on? field and who the feed item is being shared with.
publisher.getPayload
Fired by the publisher when the Chatter feed page is initially loaded.publisher.setupPanel
Fired by the canvas app to indicate to the publisher that the content being
sent to the publisher should be shared in the feed item. This event is in
publisher.setPayload
response to publisher.getPayload and contains information about
the feed item youre trying to create. You can create three feed item types:
TextPost
LinkPost
CanvasPost
71
Canvas SDK Publisher EventsCanvas Apps in the Publisher
DescriptionField
Fired by the canvas app to indicate to the publisher that the canvas app is
ready to submit a payload. After this event fires, the Share button becomes
active.
This code snippet enables the Share button:
$$.client.publish(sr.client,
{name : 'publisher.setValidForSubmit',
payload : true});
publisher.setValidForSubmit
Fired by the publisher when the user selects a canvas app in the publisher.
This event indicates that the canvas app is being displayed. A Visualforce
page can also listen for this event.
publisher.showPanel
Fired by the publisher after the Share button is clicked and data is successfully
submitted.
publisher.success
Sequence of Publisher Events
Heres the order of publisher events from the perspective of the canvas app:
1. The canvas app listens for publisher.setupPanel.
2. The canvas app listens for publisher.showPanel.
3. The user interacts with the canvas app, for example, clicks a button or enters some text. The canvas app does any validation required
and then fires publisher.setValidForSubmit. As a result, the publisher then enables the Share button.
4. The canvas app listens for publisher.getPayload.
5. The canvas app fires publisher.setPayload.
6. The canvas app listens for publisher.success.
7. The canvas app listens for publisher.failure.
8. The canvas app listens for publisher.clearPanelState.
SEE ALSO:
Create the Action Manually
Publisher Context Considerations
Publisher Context Considerations
When you display a canvas app inside the publisher, the context information you receive from the signed request or from a
getContext() call contains information specific to the publisher:
LocationIf the canvas app is in the publisher, then the Environment.displayLocation field contains the value
Publisher.
SizeThe Environment.Dimensions object contains information about the size of the canvas app.
The canvas app height will be the height you specify in the quick action that you created.
72
Publisher Context ConsiderationsCanvas Apps in the Publisher
If you selected Create Actions Automatically when you created the canvas app, the canvas app height defaults
to 200 pixels.
The canvas app width defaults to 521 pixels, which is the same as the maximum width of a canvas app in the publisher.
The maximum height of a canvas app in the publisher is 500 pixels.
The maximum width of a canvas app in the publisher is 521 pixels.
This code snippet shows the default size values of a canvas app in the publisher:
"dimensions":
{
"width": "521px",
"height": "200px",
"maxHeight": "500px",
"maxWidth": "521px"
}
The publisher is a fixed width of 521 pixels. For example, if you resize your canvas app to be 400 pixels, the publisher width
remains 521 pixels.
You can use the resize() method in the Canvas SDK to change the values of your canvas app up to the maxHeight and
maxWidth.
SEE ALSO:
Create the Action Manually
Environment
Dimensions
Resizing a Canvas App
Publisher Canvas App Access Considerations
Canvas Apps in the Chatter Feed
Publisher Canvas App Access Considerations
When modifying a canvas app that appears in the publisher, keep these considerations in mind:
If the canvas app has a quick action associated with it, then you cant delete the canvas app or remove the Publisher location. You
must first delete the quick action.
If the user doesnt have access to the canvas app through profiles or permission sets and they select the app in the publisher, then
theyll receive an error.
If the canvas app attempts to perform an action for which the user doesnt have permissions, then that action will fail and the canvas
app will receive an error. For example, if the app tries to create a Merchandise record but the user doesnt have create permission
on Merchandise, then the app will receive an error. The canvas app should then relay the error to the user.
73
Publisher Canvas App Access ConsiderationsCanvas Apps in the Publisher
CHAPTER 9 Canvas Apps in the Chatter Feed
Canvas enables you to expose your canvas apps as feed items. The feed gives users information about
whats happening inside of Salesforce and information about records and groups theyre following.
In this chapter ...
Chatter Feed Context
Considerations
Developers can use canvas apps in the feed to:
Post to the Chatter feed from a canvas app in the publisher or through Connect REST API or Connect
in Apex.
Chatter Feed Canvas
App Access
Considerations
Display a canvas app inside a Chatter feed item.
When you create a canvas app Chatter feed item, it contains a thumbnail image, a link title, and a
description. In Salesforce Classic, when the user clicks on the link or the description, the canvas app
opens up in the feed. If the user clicks the link again, the content is collapsed, giving users a seamless
experience for working in their feed. In Lightning Experience, when the user clicks on the link or the
description, the user is redirected to a dedicated canvas app page.
For example, you might have a canvas app that allows a user to log their hours worked. You can now
programmatically create a feed item that displays a canvas app which shows the user their currently
logged hours.
In addition, the feed item could display actions depending on the current user. So the canvas app could
then post a feed item to the users manager, and the manager could approve or deny the hours logged.
Since the content is served from the canvas app, the developer has full control over the behavior.
SEE ALSO:
Publisher Context Considerations
Canvas Apps in the Publisher
Chatter Feed Context Considerations
74
Chatter Feed Context Considerations
When you display a canvas app inside of a feed item, the context information you receive from the signed request or from a
getContext() call contains information specific to the feed:
LocationIf the canvas app is in the feed, then the Environment.displayLocation field contains the value
ChatterFeed.
ParametersWhen you create a feed item that contains a canvas app, you can specify a JSON string as the parameters value. When
the canvas app receives the context, the parameters in the feed item will be contained in the Environment.Parameters
object.
SizeThe Environment.Dimensions object contains information about the size of the canvas app.
The canvas app height defaults to 100 pixels.
The canvas app width defaults to 420 pixels, which is the same as the maximum width of a canvas app in the feed.
The maximum height of a canvas app in the feed is 400 pixels.
The maximum width of a canvas app in the feed is 420 pixels.
This code snippet shows the default size values of a canvas app in the feed:
"dimensions":
{
"width": "420px",
"height": "100px",
"maxHeight": "400px",
"maxWidth": "420px"
}
The feed is a fixed width of 420 pixels. For example, if you resize your canvas app to be 200 pixels, the feed width remains 420
pixels.
You can use the resize() method in the Canvas SDK to change the values of your canvas app up to the maxHeight and
maxWidth.
SEE ALSO:
Canvas Apps in the Chatter Feed
Environment
Dimensions
Resizing a Canvas App
Chatter Feed Canvas App Access Considerations
Chatter Feed Canvas App Access Considerations
When modifying a canvas app that appears in the feed, keep these considerations in mind:
If the canvas app is deleted and that app is in feed items, those feed items will remain. If a user accesses one of those feed items,
theyll receive an error that the canvas app doesnt exist.
If you remove a users access to a canvas app and that app is in feed items, those feed items will remain. If a user accesses one of
those feed items, theyll receive an error that they dont have permissions to access the canvas app.
75
Chatter Feed Context ConsiderationsCanvas Apps in the Chatter Feed
When creating a canvas app feed item either through a publisher action or through Connect REST API or Connect in Apex, Salesforce
checks to see if the canvas app exists and if the user has permissions to it.
If the canvas app doesnt exist, the feed item cant be created and an error is returned.
If the canvas app exists, but the user attempting to create the feed item doesnt have access to the canvas app, the feed item is
created. However, the user wont be able to view the feed item and an error is returned.
If the canvas app attempts to perform an action for which the user doesnt have permissions, then that action will fail and the canvas
app will receive an error. For example, if the app tries to create a Merchandise record but the user doesnt have create permission
on Merchandise, then the app will receive an error. The canvas app should then relay the error to the user.
SEE ALSO:
Chatter Feed Context Considerations
CanvasRequest
76
Chatter Feed Canvas App Access ConsiderationsCanvas Apps in the Chatter Feed
CHAPTER 10 Canvas in the Salesforce Mobile App
Canvas enables you to expose your canvas apps in the Salesforce mobile app. The Salesforce mobile
app is Salesforce on the go. This enterprise-class mobile app gives you real-time access to the same
In this chapter ...
Set Canvas App
Location and Add it
information that you see in the office, but its organized for getting work done when youre away from
your desk. Just like in the full Salesforce site, users can access publisher and Chatter feed items, including
Canvas apps.
to the Navigation
Menu
Developers can use canvas apps in the Salesforce mobile app to:
Salesforce Mobile
App Context
Considerations
Expose a canvas app as an action. An icon indicates a canvas app. You can use either the default
puzzle icon or upload a custom icon for the related action.
Salesforce Mobile
App Access
Considerations
Post to the feed from a canvas app in Salesforce or through Connect REST API or Connect in Apex.
Display a canvas app inside a feed item from within the Salesforce mobile app. An icon indicates a
canvas app. You can use either the default puzzle icon or provide a thumbnail URL in the feed item
to display a custom icon.
Salesforce Mobile
App Custom Icons
Add a canvas app as an option in the navigation menu. An icon indicates a canvas app. You can use
the default puzzle icon or provide a custom icon URL in the connected app settings of your canvas
app.
Salesforce Mobile
App Navigation
Methods for Use with
Canvas Apps
Note: Canvas apps dont appear in the app navigation menu in Salesforce for Android. To
see canvas apps in the navigation menu, log in to Salesforce mobile web.
For example, you might have a canvas app that warehouse employees use to process orders on a mobile
device. You can create an action that accesses the app from the icon of the device, allowing employees
to pull up a list of customer orders. After an order is processed, the app sets the order status in Salesforce
and posts a feed item to the associated customer account.
Users can still access your canvas app from within Salesforce on a desktop machine. The additional
functionality for mobile devices that Salesforce offers doesnt impact or limit existing functionality.
SEE ALSO:
Canvas Apps in the Publisher
Canvas Apps in the Chatter Feed
Salesforce Mobile App Access Considerations
Salesforce Mobile App Context Considerations
Salesforce Mobile App Custom Icons
77
Set Canvas App Location and Add it to the Navigation Menu
To add a canvas app to appear in the Salesforce mobile app navigation menu, you must set the location and add it to the mobile
navigation.
1. In Salesforce, from Setup, enter Apps in the Quick Find box, then select Apps.
2. In the Connected Apps related list, click the app you want to make available in the navigation pane and click Edit.
3. In the Canvas App Settings section, select Canvas.
4. In the Locations field, select Mobile Nav and click Add.
5. Click Save.
6. For the canvas app to appear in the navigation menu you must add it to the mobile navigation. From Setup, enter Navigation
in the Quick Find box, then select Salesforce Navigation.
7. From the available menu items, select your app and click Add.
8. Click Save.
Salesforce Mobile App Context Considerations
Keep these considerations in mind when you display a canvas app inside of the Salesforce mobile app.
When you display a canvas app inside of the feed or publisher, the canvas context you receive (either from the Signed Request or from
the getContext call) contains information specific to the Salesforce mobile app publisher.
You can verify youre on either the feed or publisher by looking at the displayLocation value in the environment section.
For publisher, displayLocation is set to Publisher. For the feed, displayLocation is set to ChatterFeed.
When creating a Canvas feed item, you can specify a JSON string as the parameters value. When the context is sent, any value in
the parameters field on the feed item is sent in the parameters of the environment section of the context.
As with any canvas app, the context contains information about the apps dimensions. Since Salesforce is designed for mobile, the
sizes we provide for it are different than the ones we provide for the full Salesforce sites.
To create a single-finger touch scrolling experience:
Ensure that the outermost div elements contain the following properties.
min-height: 250px;
overflow: scroll;
width: 100%;
-webkit-overflow-scrolling: touch;
-webkit-transform: translated(0%,0px,0px);
Set the height attribute to the clientHeight value delivered in the signed request. For example:
// Where sr is a parsed signed request object.
var h = parseInt(sr.context.environment.dimensions.clientHeight, 10);
Sfdc.canvas.byId('divElementId').style.height = h;
The clientHeight value can be very small, particularly in a phones landscape mode, and users might not be able to see
any content. Use min-height set to the desired height in pixels to ensure a good user experience.
78
Set Canvas App Location and Add it to the Navigation MenuCanvas in the Salesforce Mobile App
In the navigation menu, the default puzzle icon size is 60 pixels by 60 pixels.
SEE ALSO:
Canvas in the Salesforce Mobile App
Salesforce Mobile App Access Considerations
Resizing a Canvas App
Salesforce Mobile App Custom Icons
Salesforce Mobile App Access Considerations
Keep these considerations in mind when modifying a canvas app that appears in the Salesforce mobile app.
By necessity, the Salesforce mobile app layout is different than the full Salesforce site layout that youre used to. Remember the following
when creating a canvas app for use in the Salesforce mobile app.
Because canvas apps are designed to display your third-party application inside of Salesforce, the device must have access to your
canvas app URL. If your app is only accessible behind a firewall, the mobile device must be behind the firewall, too. If users dont
have access to the canvas URL, they receive an errorpossibly a 404 or 500 error.
When accessing your canvas app as an action, if the canvas app uses the What are you working on header, the header is fixed at
the top of the page and your canvas app scroll area falls below the header text box.
The canvas app link and description in the feed might display fewer characters than what is displayed in the full Salesforce site.
Depending on the device you use, the feed screen can change if the device is rotated. Your canvas app should support rotation if
possible. Use the orientation event to handle changes in device orientation.
The heights used in the Salesforce mobile app and the full Salesforce site are different. Use the Dimensions object in the signed
request to render your actions correctly in the publisher.
In the action menu, long action labels might be truncated.
The feed layout is different than that of the full Salesforce site. Instead of an app opening in the feed, a page opens that displays the
canvas app on the entire screen. To return to the Salesforce mobile app, tap .
When you view the action bar or Feed, the default Canvas puzzle icon displays for canvas apps. You can override this default action
icon with an image you provide.
When a canvas app appears as an option in the navigation menu, the default Canvas puzzle icon is used. You can customize the
icon in the connected app settings of your canvas app.
Canvas apps arent available when the user accesses Salesforce offline.
SEE ALSO:
Canvas in the Salesforce Mobile App
Salesforce Mobile App Context Considerations
Salesforce Mobile App Custom Icons
Dimensions
Handling Orientation Changes in Your Canvas App
Alternatives to Cookies for User Tracking
79
Salesforce Mobile App Access ConsiderationsCanvas in the Salesforce Mobile App
Salesforce Mobile App Custom Icons
Custom icons help distinguish your app in the Salesforce mobile app. If you dont customize the icon for your app, youll get the default
puzzle-piece icon.
You can customize the icon that is used in the Salesforce navigation menu. You set this icon in the Icon URL entry in the Basic Information
section of the connected app settings for your canvas app. From Setup, enter Apps in the Quick Find box, then select Apps and click
Edit for your connected app. The icon URL must be a secure HTTPS URL that points to an icon image file. The image file must be in the
GIF, JPG, or PNG file format. For the Salesforce navigation menu, the icon cannot be larger than 60 pixels high by 60 pixels wide.
The custom icon that is used in the Salesforce navigation menu is also used in the Chatter tab and the Canvas App Previewer. If your
canvas app will be shown in the navigation menu, we recommend that you use a 60x60 pixel size icon and let Salesforce automatically
resize the icon to the smaller size that is needed for the Chatter tab and the Canvas App Previewer.
You can also customize the icon that is used in the Salesforce action bar and action menu for a canvas app. The action bar uses the
custom icon set for the action that accesses the canvas app, not the custom icon that is associated with the connected app. You set the
action icons by uploading a static resource file for your custom icon and then using this static resource as the icon for the global action.
The static resource icon file should be in the PNG format, with a size of 120 pixels high by 120 pixels wide. See Custom Icon Guidelines
and Best Practices in the Salesforce Mobile App Developer Guide for more guidelines on custom action icons.
SEE ALSO:
Canvas in the Salesforce Mobile App
Salesforce Mobile App Context Considerations
Salesforce Mobile App Navigation Methods for Use with Canvas Apps
The Canvas framework includes methods that you can use to smoothly integrate navigation between a canvas app and the Salesforce
mobile app, without needing to use Visualforce.
To circumvent the navigational limitations of the iframe that contains a canvas app, use Canvas methods. These methods offer a simpler
alternative to Visualforce pages for controlling navigation to or from canvas apps in the Salesforce app.
For example, your canvas app code can call Salesforce "create record" logic to navigate to the page where the Create Account button
resides. Clicking the button triggers a navigation method to go to the record creation page, which is outside of the canvas app.
These methods within the Canvas framework are events that reside in the JavaScript library. When you call one of the navigation methods
from your canvas code, you send an event into Salesforce that reads the payload and directs the user to the specified destination.
Calling the methods from your canvas app is slightly different than calling functions from a Visualforce page, because the methods are
proxied to the Salesforce container through the Canvas cross-domain API.
Reference the navigation method as an event variable, with name and payload. For example:
var event = {name:"s1.createRecord", payload: {entityName: "Account", recordTypeId:
"00h300000001234"}};
The following table shows the name, payload, and purpose of the navigation methods in Salesforce.
80
Salesforce Mobile App Custom IconsCanvas in the Salesforce Mobile App
DescriptionPayloadName
Navigates to the previous state thats saved in the sforce.one history. Its
equivalent to clicking a browsers Back button.
refresh is optional. By default, the page doesnt refresh. Pass true to
refresh the page if possible.
{"refresh" : true}s1.back
Navigates to an sObject record, specified by a 15-character or 18-character
recordId. This record home has several views, which in the Salesforce app
are available as slides that the user can swipe between.
view is optional and defaults to detail. view specifies the slide within
record home to display initially.
{"recordId" :
"001XXXXXXXXXXXX",
"view" : "chatter"}
s1.navigateTo
SObject
Note: Record IDs corresponding to ContentNote SObjects arent
supported.
The possible values are:
detail: the record detail slide
chatter: the Chatter slide
related: the view of related slide
Navigates to the specified URL.
Relative and absolute URLs are supported. Relative URLs are relative to the
Lightning domain, and retain navigation history. External URLsthat is, URLs
that are outside the Lightning domainopen in a separate browser window.
{"url" :
"https://salesforce.com/
apex/v.apexp",
"isredirect" : true}
s1.navigateTo
URL
Note: Depending on the users device platform, device settings, version
of Salesforce, and authentication requirements for the external URL being
opened, the separate browser window might require authentication or
reauthentication.
Use relative URLs to navigate to different screens within your app. Use external
URLs to allow the user to access a different site or app, where those actions
dont need to be preserved in your app. To return the user to your app, the
separate window thats opened by an external URL must be closed when the
user is finished with the other app. The new window has a separate history from
your app, and this history is discarded when the window is closed. Discarding
the history of a new window prevents the user from clicking a Back button to
go back to your app; the user must close the new window.
mailto:, tel:, geo:, and other URL schemes are supported for launching
external apps and attempt to do the right thing. However, support varies by
mobile platform and device. mailto: and tel: are reliable, but we
recommend that you test any other URLs on a range of expected devices.
isredirect is optional and defaults to false. Set it to true to indicate
that the new URL should replace the current one in the navigation history.
Note: Be careful when using navigateToURL within the onClick
handler of an <apex:commandButton> or any <button
type="submit"> or <input type="submit">. Even if
81
Salesforce Mobile App Navigation Methods for Use with
Canvas Apps
Canvas in the Salesforce Mobile App
DescriptionPayloadName
isredirect=true, the default click action of the command button
is a form post. In this scenario, the command button performs a form
post and a navigateToURL action, requiring the user to click the
back button twice to navigate to the previous page. To prevent the
default click action, configure the onClick handler to either call
event.preventDefault() or return false.
Note: URLs corresponding to ContentNote SObjects arent supported.
Navigates to the feed of the specified type, scoped to the subjectId. For
some feed types, the subjectId is required but ignored. For those feed
types, pass the current users ID as the subjectId.
The possible values for type are:
{"subjectId" :
"001XXXXXXXXXXXX",
"type" : "NEWS"}
s1.navigateTo
Feed
BOOKMARKS: Contains all feed items saved as bookmarks by the context
user. Pass the current users ID as the subjectId.
COMPANY: Contains all feed items except feed items of type
TrackedChange. To see the feed item, the user must have sharing
access to its parent.Pass the current users ID as the subjectId. Pass the
current users ID as the subjectId.
FILES: Contains all feed items that contain files posted by people or groups
that the context user follows. Pass the current users ID as the subjectId.
GROUPS: Contains all feed items from all groups the context user either
owns or is a member of. Pass the current users ID as the subjectId.
NEWS: Contains all updates for people the context user follows, groups the
user is a member of, and files and records the user is following. Contains all
updates for records whose parent is the context user. Pass the current users
ID as the subjectId.
PEOPLE: Contains all feed items posted by all people the context user
follows. Pass the current users ID as the subjectId.
RECORD: Contains all feed items whose parent is a specified record, which
could be a group, user, object, file, or any other standard or custom object.
When the record is a group, the feed also contains feed items that mention
the group. When the record is a user, the feed contains only feed items on
that user. You can get another users record feed. Pass the records ID as the
subjectId.
TO: Contains all feed items with mentions of the context user. Contains feed
items the context user commented on and feed items created by the context
user that are commented on. Pass the current users ID as the subjectId.
TOPICS: Contains all feed items that include the specified topic. Pass the
topics ID as the subjectId. This value is supported in Salesforce for
mobile web only. Topics arent available in Salesforce for iOS or Salesforce
for Android.
82
Salesforce Mobile App Navigation Methods for Use with
Canvas Apps
Canvas in the Salesforce Mobile App
DescriptionPayloadName
Navigates to the specific feed item, feedItemId, and any associated
comments.
{"feedItemId" :
"001XXXXXXXXXXXX"}
s1.navigateTo
FeedItemDetail
Navigates to a related list for the parentRecordId. For example, to display
a related list for a Warehouse object, the parentRecordId is
Warehouse__c.Id.
relatedListId is the API name or ID of the related list to display.
{"relatedListId" :
"001XXXXXXXXXXXX",
"parentRecordId" :
"001XXXXXXXXXXXX" }
s1.navigateTo
RelatedList
Navigates to the list view thats specified by the listViewId, which is the
ID of the list view to be displayed.
listViewName sets the title for the list view. It doesnt need to match the
actual name thats saved for the list view. To use the saved name, set
listViewName to null.
{"listViewId" :
"001XXXXXXXXXXXX",
"listViewName" :
"myListView", "scope"
: "scope"}
s1.navigateTo
List
Set scope to the name of the sObject in the view, for example, Account or
MyObject__c.
Opens the page to create a record for the specified entityName, for example,
Account or MyObject__c.
recordTypeId is optional and specifies the record type for the created
object. Calling createRecord without providing a recordTypeId may
result in an error.
{"entityName" :
"MyObject__c",
"recordTypeId" :
"001XXXXXXXXXXXX"}
s1.create
Record
Opens the page to edit the record specified by recordId.{"recordId" :
"001XXXXXXXXXXXX"}
s1.editRecord
For information about navigation methods for use with Visualforce, see the Salesforce Mobile App Developers Guide.
SEE ALSO:
Visualforce Considerations
Canvas in the Salesforce Mobile App
83
Salesforce Mobile App Navigation Methods for Use with
Canvas Apps
Canvas in the Salesforce Mobile App
CHAPTER 11 Customizing Your App Lifecycle
By providing a custom Apex class, you can control the context information thats sent to your canvas
app and add custom behavior when your app is rendered.
In this chapter ...
Creating a
CanvasLifecycleHandler
Salesforce provides several Apex interfaces and classes in the Canvas namespace that provide additional
control over the canvas app lifecycle. You can use the Canvas namespace and the CanvasLifecycleHandler
interface to:
Associating Your
CanvasLifecycleHandler
with Your App
Control what sections of the CanvasRequest Context data get sent to your app. You can, for example,
require that Salesforce never send the Organization information in the CanvasRequest data. Excluding
Filtering
CanvasRequest
Context Data
sections of context data improve performance by reducing the amount of data thats sent in the
request and remove the need to process the organization data in your app.
Retrieve application context data when the app is rendered and alter the behavior of your app
accordingly. You can obtain the application version and, depending on the version, change how
the app runs.
Controlling Canvas
App Behavior
Presenting User Error
Messages
Modify some of the context data, such as the canvas app URL, custom parameters, or the list of object
fields that are returned in the Record data when the app is rendered.
Testing Your
CanvasLifecycleHandler
Implementation
Present a well-formed error message to the user in the Salesforce UI if something goes wrong.
Salesforce also provides a Test class in the Canvas namespace that you can use to create test context
data and verify the behavior of your lifecycle handler without having to run your app.
Distributing Your
CanvasLifecycleHandler
Class
Reference documentation for the Apex Canvas namespace is provided in the Apex Code Developer Guide.
84
Creating a CanvasLifecycleHandler
You can control your app lifecycle by providing an implementation of the Canvas.CanvasLifecycleHandler Apex interface that Salesforce
can use.
The Apex Canvas.CanvasLifecycleHandler interface provides methods and callbacks for customizing app lifecycle behavior. Salesforce
will use your implementation at runtime to let you run custom code. Use the following steps to create an implementation of the
Canvas.CanvasLifecycleHandler interface.
1. From Setup, enter Apex Classes in the Quick Find box, then select Apex Classes.
2. Click New to create a Apex class.
3. Create an Apex class that implements the Canvas.CanvasLifecycleHandler interface. You must implement the
excludeContextTypes() and onRender() methods. Heres a template example:
public class MyCanvasLifecycleHandler
implements Canvas.CanvasLifecycleHandler {
public Set<Canvas.ContextTypeEnum> excludeContextTypes(){
Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();
// Code goes here to add items to excluded list
// that should be excluded from Context data
return excluded;
}
public void onRender(Canvas.RenderContext renderContext) {
// Code goes here to customize behavior when the app is rendered
}
}
4. After youve finished adding your code, save the Apex class.
5. Optionally test your implementation by using the Canvas.Test class.
6. To let Salesforce know which implementation to use for your app, associate your Apex class with your app.
SEE ALSO:
Testing Your CanvasLifecycleHandler Implementation
Associating Your CanvasLifecycleHandler with Your App
Associating Your CanvasLifecycleHandler with Your App
After youve created an Apex implementation class for CanvasLifecycleHandler, you need to associate it with your canvas app by adding
the class name to your canvas app configuration settings.
Use the following steps to associate a Canvas.CanvasLifecycleHandler implementation with your canvas app.
1. From Setup, enter Apps in the Quick Find box, then select Apps.
2. Under Connected Apps, select the canvas app that you need to modify and click Edit.
85
Creating a CanvasLifecycleHandlerCustomizing Your App Lifecycle
3. On the connected app edit page, under Canvas App Settings, add the Apex CanvasLifecycleHandler class name that you created
into the Lifecycle Class field.
Filtering CanvasRequest Context Data
To filter out parts of the CanvasRequest Context data that gets sent to your canvas app, you need to provide an implementation of
Canvas.CanvasLifecycleHandler.excludeContextTypes().
Salesforce calls your implementation of excludeContextTypes() to determine what context information is sent to your app.
Your implementation returns a set of context data to exclude or returns null (or an empty set) if you need to receive all context data.
The set consists of values from the Canvas.ContextTypeEnum Apex enum type.
The enum values are used as follows::
ORGANIZATION: Exclude context information about the organization in which the canvas app is running.
RECORD_DETAIL: Exclude context information about the object record on which the canvas app appears.
USER: Exclude context information about the current user.
Heres an example excludeContextTypes() implementation that excludes the Organization and User context data:
public Set<Canvas.ContextTypeEnum> excludeContextTypes(){
Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>();
// Exclude the Organization and User context data
excluded.add(Canvas.ContextTypeEnum.ORGANIZATION);
excluded.add(Canvas.ContextTypeEnum.USER);
return excluded;
}
When your canvas app receives CanvasRequest Context data, the JSON data does not include the organization and user sections.
Reference documentation for the Apex Canvas.ContextTypeEnum is provided in the Apex Code Developer Guide.
Controlling Canvas App Behavior
To modify the default behavior of the signed request, you need to provide an Apex class that implements
Canvas.CanvasLifecycleHandler.onRender() and associate this class with your canvas app. In your onRender()
implementation, you can control app behavior with custom code.
Salesforce calls your implementation of onRender() just before your app is rendered. Current context information is passed to this
method in the Canvas.RenderContext parameter.
In your onRender() implementation, you can retrieve the following context information.
Application context data, such as the canvas app name, URL, version, and namespace.
Environment context data, such as the display location and sublocation, object field names, and custom parameters.
You can set the following context information.
The portion of the canvas app URL after the app domain.
The list of object fields for which Salesforce will return Record context data if the canvas app appears on an object page. One way a
canvas app can appear on an object page is if the canvas app appears on a Visualforce page through the use of the
<apex:canvasApp> component and that Visualforce page is associated with an object.
86
Filtering CanvasRequest Context DataCustomizing Your App Lifecycle
The custom parameters that are passed to the canvas app.
You can also use Canvas.CanvasRenderException to present an error message to the user in the Salesforce by throwing a
Canvas.CanvasRenderException.
Heres an example onRender() implementation that:
Checks the app version information and, if the version is unsupported, throws a CanvasRenderException.
Overrides the current canvas app URL, appending /alternatePath to the domain portion of the original URL.
Sets the list of object fields to include Name, BillingAddress, and YearStarted, anticipating that the canvas app will appear on the
Account page.
Overrides the set of custom parameters by adding a new newCustomParam parameter. Note that the current set of parameters is
first retrieved and cached locally. The new parameter is added to the cached list to ensure that you dont lose the current set of
custom parameters when you call setParametersAsJSON().
public void onRender(Canvas.RenderContext renderContext) {
// Get the Application and Environment context from the RenderContext
Canvas.ApplicationContext app = renderContext.getApplicationContext();
Canvas.EnvironmentContext env = renderContext.getEnvironmentContext();
// Check the application version
Double currentVersion = Double.valueOf(app.getVersion());
if (currentVersion <= 5){
// Versions lower than 5 are no longer supported in this example
throw new Canvas.CanvasRenderException('Error: Versions earlier than 5 are no
longer supported.');
}
// Override app URL, replacing portion after domain with '/alternatePath'
app.setCanvasUrlPath('/alternatePath');
// Add Name, BillingAddress and YearStarted to fields
// (assumes we'll run from a component on the Account detail page)
Set<String> fields = new Set<String>{'Name','BillingAddress','YearStarted'};
env.addEntityFields(fields);
// Add a new custom param to the set of custom params
// First, get the current custom params
Map<String, Object> previousParams =
(Map<String, Object>) JSON.deserializeUntyped(env.getParametersAsJSON());
// Add a 'newCustomParam' to our Map
previousParams.put('newCustomParam','newValue');
// Now, replace the parameters
env.setParametersAsJSON(JSON.serialize(previousParams));
}
Presenting User Error Messages
You can use Canvas.CanvasRenderException to display error messages to the user.
If you throw a CanvasRenderException from your onRender() implementation, the error message in that exception will be displayed
to the user in the Salesforce UI. This exception will be managed only within the onRender() method.
87
Presenting User Error MessagesCustomizing Your App Lifecycle
CanvasRenderException supports all the standard Apex exception class methods and constructors. See Exception Class and Build-In
Exceptions in the Apex Code Developer Guide for more information on Apex exceptions.
Heres an example onRender() implementation that throws a Canvas.CanvasRenderException. Salesforce uses this exception and
displays Error: Could not set URL as the user error message.
public void onRender(Canvas.RenderContext renderContext) {
// Code omitted that determines if the error condition occured
...
throw new Canvas.CanvasRenderException('Error: Could not set URL.');
}
If the canvas app is run from the Salesforce Chatter tab, the error message resembles:
Testing Your CanvasLifecycleHandler Implementation
You can use the Canvas.Test class to test your Canvas.CanvasLifecycleHandler.onRender() implementation without
having to run your canvas app.
Use Canvas.Test to create a test Canvas.RenderContext with mock application and environment context data. Call
Canvas.Test.testCanvasLifecycle() with the mock RenderContext and your CanvasLifecycleHandler implementation
to verify that your CanvasLifecycleHandler is being invoked correctly.
Use Canvas.Test.mockRenderContext() to create a mock RenderContext. You can provide initial mock application and
environment context data or let Canvas.Test use a default set of mock data. You provide initial mock application and environment context
data in two Maps of key-value pairs. Use the predefined Canvas.Test key name constants as your keys. The following example sets the
app name in the application context data and the sublocation in the environment context data.
Map<String,String> appValues = new Map<String,String>();
appValues.put(Canvas.Test.KEY_NAME,'AppName');
Map<String,String> envValues = new Map<String,String>();
envValues.put(Canvas.Test.KEY_SUB_LOCATION,'mobileDevice');
For the full list of context keys that Canvas.Test provides, see Test Constants in the Apex Code Developer Guide.
When youve got a mock RenderContext, you can call Canvas.Test.testCanvasLifecycleHandler() with the
RenderContext and your CanvasLifecycleHandler. This call invokes the handlers onRender() method, and passies the mock
RenderContext as context data.
Heres an example test class that uses Canvas.Test. The test class has three methods.
88
Testing Your CanvasLifecycleHandler ImplementationCustomizing Your App Lifecycle
testDefaultMockValues() invokes MyCanvasLifecycleHandler, using the default Canvas.Test mock context data.
testOverriddenAppValues() invokes MyCanvasLifecycleHandler, using a custom mock RenderContext with mock app
URL and version application context data.
testOverriddenEnvironmentValues() invokes MyCanvasLifecycleHandler, using a custom mock RenderContext with
mock display location, location URL, and custom parameter environment context data. The custom parameters are set through the
Canvas.EnvironmentContext interface after the mock RenderContext is created.
-@isTest
global class MyCanvasLifecycleHandlerTest {
static testMethod void testDefaultMockValues(){
// Test handler using the default mock RenderContext Canvas.Test creates
MyCanvasLifecycleHandler handler = new MyCanvasLifecycleHandler();
Canvas.Test.testCanvasLifecycle(handler,null);
}
static testMethod void testOverriddenAppValues(){
// Test handler with some mock application context values
Map<String,String> appValues = new Map<String,String>();
appValues.put(Canvas.Test.KEY_CANVAS_URL,'https://myserver.com:6000/myAppPath');
appValues.put(Canvas.Test.KEY_VERSION,'3.0');
Canvas.RenderContext mock = Canvas.Test.mockRenderContext(appValues,null);
MyCanvasLifecycleHandler handler = new MyCanvasLifecycleHandler();
Canvas.Test.testCanvasLifecycle(handler,mock);
}
static testMethod void testOverriddenEnvironmentValues(){
// Test handler with some mock environment context values
Map<String,String> envValues = new Map<String,String>();
envValues.put(Canvas.Test.KEY_DISPLAY_LOCATION,'Chatter');
envValues.put(Canvas.Test.KEY_LOCATION_URL,
'https://myinstance.salesforce.com/_ui/core/chatter/ui/ChatterPage');
MyCanvasLifecycleHandler handler = new MyCanvasLifecycleHandler();
Canvas.RenderContext mock = Canvas.Test.mockRenderContext(null,envValues);
// Directly update the mock RenderContext and set the custom parameters
mock.getEnvironmentContext().setParametersAsJSON(
'{\"one\":1,\"two\":2,\"bool\":true,\"stringVal\":\"some string\"}');
Canvas.Test.testCanvasLifecycle(handler,mock);
}
}
Distributing Your CanvasLifecycleHandler Class
If you package and distribute your canvas app, make sure to include your CanvasLifecycleHandler class in your package.
Use the following steps to include your CanvasLifecycleHandler implementation in your canvas app package.
1. In Salesforce, from Setup, enter Packages in the Quick Find box, then select Packages.
2. Find the package for your canvas app, and then click the package name to go to the package detail page.
3. On the package detail page, under Components, click Add.
89
Distributing Your CanvasLifecycleHandler ClassCustomizing Your App Lifecycle
4. In the Add to Package page, in the Component Type field, select Apex Class. A list of available Apex classes is shown.
5. Select the checkbox next to your Apex class for your CanvasLifecycleHandler implementation, and then click Add To Package.
90
Distributing Your CanvasLifecycleHandler ClassCustomizing Your App Lifecycle
REFERENCE
CHAPTER 12 Objects
Canvas provides an SDK that contains objects that enable communication between your canvas app and Salesforce.
CanvasRequest
Controller
SignedRequest
SEE ALSO:
CanvasRequest
SignedRequest
CanvasRequest
When you use a signed request for authentication in your canvas app, you receive a CanvasRequest object in the initial POST message
from Salesforce. This object contains fields related to the request, and also contains the Context and Client objects. The CanvasRequest
object is returned in JSON format and contains the following fields.
DescriptionField
The algorithm used to sign the request.algorithm
For internal use only.issuedAt
The context users ID.userId
The following code snippet shows an example of the CanvasRequest object.
{
"context":
{
"application":
{
"applicationId":"06Px000000003ed",
"authType":"SIGNED_REQUEST",
"canvasUrl":"http://MyDomainName.my.salesforce.com:8080
/canvas_app_path/canvas_app.jsp",
"developerName":"my_java_app",
"isInstalledPersonalApp": false,
"name":"My Java App",
"namespace":"org_namespace",
91
"options":[],
"referenceId":"09HD00000000AUM",
"samlInitiationMethod":"None",
"version":"1.0.0"
},
"user":
{
"accessibilityModeEnabled":false,
"currencyISOCode":"USD",
"firstName":"Sean",
"fullName":"Sean Forbes",
"isDefaultNetwork":false,
"language":"en_US",
"lastName":"Forbes",
"locale":"en_US",
"networkId":"0DBxx000000001r",
"profileId":"00ex0000000jzpt",
"profilePhotoUrl":"/profilephoto/005/F",
"profileThumbnailUrl":"/profilephoto/005/T",
"roleId":null,
"siteUrl":"https://MyDomainName.my.site.com/",
"siteUrlPrefix":"/mySite",
"timeZone":"America/Los_Angeles",
"userId":"005x0000001SyyEAAS",
"userName":"[email protected]",
"userType":"STANDARD"
},
"environment":
{
"parameters":
{
"complex":
{
"key1":"value1",
"key2":"value2"
},
"integer":10,
"simple":"This is a simple string.",
"boolean":true
},
"dimensions":
{
"clientHeight":"50px",
"clientWidth":"70px",
"height":"900px",
"width":"800px",
"maxHeight":"2000px",
"maxWidth":"1000px"
},
"record":
{
"attributes":
92
CanvasRequestObjects
{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
},
"displayLocation":"Chatter",
"locationUrl":"https://salesforce.com/some/path/index.html",
"subLocation":null,
"uiTheme":"Theme3",
"version":
{
"api":"61.0",
"season":"SUMMER"
},
},
"organization":
{
"currencyIsoCode":"USD",
"multicurrencyEnabled":true,
"name":"Edge Communications",
"namespacePrefix":"org_namespace",
"organizationId":"00Dx00000001hxyEAA"
},
"links":
{
"chatterFeedItemsUrl":"/services/data/v61.0/chatter/feed-items",
"chatterFeedsUrl":"/services/data/v61.0/chatter/feeds",
"chatterGroupsUrl":"/services/data/v61.0/chatter/groups",
"chatterUsersUrl":"/services/data/v61.0/chatter/users",
"enterpriseUrl":"/services/Soap/c/61.0/00Dx00000001hxy",
"loginUrl":"http://MyDomainName.my.salesforce.com",
"metadataUrl":"/services/Soap/m/61.0/00Dx00000001hxy",
"partnerUrl":"/services/Soap/u/61.0/00Dx00000001hxy",
"queryUrl":"/services/data/v61.0/query/",
"recentItemsUrl":"/services/data/v61.0/recent/",
"restUrl":"/services/data/v61.0/",
"searchUrl":"/services/data/v61.0/search/",
"sobjectUrl":"/services/data/v61.0/sobjects/",
"userUrl":"/005x0000001SyyEAAS"
}
},
"client":
{
"instanceId":"06Px000000002JZ",
"instanceUrl":"http://MyDomainName.my.salesforce.com:8080",
"oauthToken":"00Dx0000X00Or4J!ARQAQJ34YL8gKowP65p8FDHkvk.Uq5...",
"refreshToken":"00DD0000000K1NM!ARAAQGJVGOyMjh1jjqvShRpLuAq0...",
"targetOrigin":"http://MyDomainName.my.salesforce.com:8080"
},
"algorithm":"HMACSHA256",
93
CanvasRequestObjects
"userId":"005x0000001SyyEAAS",
"issuedAt":null
}
Client
Context
SEE ALSO:
Objects
Client
Context
Client
The Client object is a JSON-formatted object returned by the signed request in the CanvasRequest object. It contains context information
about the client app.
DescriptionField
The ID of a canvas app exposed on a Visualforce page. Used internally for
canvas app instance management.
instanceId
The URL of the Salesforce instance. For example,
http://instance.salesforce.com. Used to preface the URLs
returned by the Links object.
instanceUrl
The OAuth access token thats returned to the caller.oauthToken
The token that the client uses to authenticate a session. This value is returned
only if the canvas app has Perform requests on your behalf at any time
refreshToken
(refresh_token, offline_access) as one of the selected OAuth scopes;
otherwise null is returned.
The URL of the canvas app. Used internally for cross-domain communication
between the page and the iFrame that contains the canvas app.
targetOrigin
The following code snippet shows an example of the Client object.
"client":
{
"instanceId":"06Px000000002JZ",
"instanceUrl":"http://instance.salesforce.com:8080",
"oauthToken":"00Dx0000X00Or4J!ARQAQJ34YLUq54RMTrQbxVoWUgorjFi3...",
"refreshToken":"00DD0000000K1NM!ARAAQGJVGOyMjh1jjqvShRpLuAq0ke...",
94
ClientObjects
"targetOrigin":"http://instance.salesforce.com:8080"
}
SEE ALSO:
CanvasRequest
Context
When you add your canvas app as a connected app in Salesforce, you can retrieve information about the current environment by using
the Context object. The Context object provides information to your app about how and by whom its being consumed. You can use
this information to make subsequent calls for information and code your app so that it appears completely integrated with the Salesforce
user interface. This object is returned in JSON format and contains the following objects:
ApplicationInformation about the canvas app, such as version, access method, URL, and so on.
EnvironmentInformation about the environment, such as location, UI theme, and so on.
LinksLinks, such as the metadata URL, user URL, Chatter groups URL, and so on. You can use these links to make calls into Salesforce
from your app.
OrganizationInformation about the organization, such as name, ID, currency code, and so on.
UserInformation about the currently logged-in user, such as locale, name, user ID, email, and so on.
The following code is an example of the Context object. The Context object is returned in the CanvasRequest object when you authenticate
using signed request. You can also explicitly make a call to get this object.
"context":{
"application":
{
"applicationId":"06Px000000003ed",
"authType":"SIGNED_REQUEST",
"canvasUrl":"http://MyDomainName.my.salesforce.com:8080
/canvas_app_path/canvas_app.jsp",
"developerName":"my_java_app",
"isInstalledPersonalApp": false,
"name":"My Java App",
"namespace":"org_namespace",
"options":[],
"referenceId":"09HD00000000AUM",
"samlInitiationMethod": "None",
"version":"1.0.0"
},
"user":
{
"accessibilityModeEnabled":false,
"currencyISOCode":"USD",
"firstName":"Sean",
"fullName":"Sean Forbes",
"isDefaultNetwork":false,
"language":"en_US",
"lastName":"Forbes",
"locale":"en_US",
"networkId":"0DBxx000000001r",
95
ContextObjects
"profileId":"00ex0000000jzpt",
"profilePhotoUrl":"/profilephoto/005/F",
"profileThumbnailUrl":"/profilephoto/005/T",
"roleId":null,
"siteUrl":"https://MyDomainName.my.site.com/",
"siteUrlPrefix":"/mySite",
"timeZone":"America/Los_Angeles",
"userId":"005x0000001SyyEAAS",
"userName":"[email protected]",
"userType":"STANDARD"
},
"environment":
{
"parameters":{},
"dimensions":
{
"clientHeight": "50px",
"clientWidth": "70px",
"height":"900px",
"width":"800px",
"maxHeight":"2000px",
"maxWidth":"1000px"
},
"record":
{
"attributes":
{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
},
"displayLocation":"Chatter",
"locationUrl":"http://MyDomainName.my.salesforce.com:8080/canvas_app_path",
"subLocation":null,
"uiTheme":"Theme3",
"version":
{
"api":"61.0",
"season":"SUMMER"
}
},
"organization":
{
"currencyIsoCode":"USD",
"multicurrencyEnabled":true,
"name":"Edge Communications",
"namespacePrefix":"org_namespace",
"organizationId":"00Dx00000001hxyEAA"
},
96
ContextObjects
"links":
{
"chatterFeedItemsUrl":"/services/data/v61.0/chatter/feed-items",
"chatterFeedsUrl":"/services/data/v61.0/chatter/feeds",
"chatterGroupsUrl":"/services/data/v61.0/chatter/groups",
"chatterUsersUrl":"/services/data/v61.0/chatter/users",
"enterpriseUrl":"/services/Soap/c/61.0/00Dx00000001hxy",
"loginUrl":"http://MyDomainName.my.salesforce.com",
"metadataUrl":"/services/Soap/m/61.0/00Dx00000001hxy",
"partnerUrl":"/services/Soap/u/61.0/00Dx00000001hxy",
"queryUrl":"/services/data/v61.0/query/",
"restUrl":"/services/data/v61.0/",
"recentItemsUrl":"/services/data/v61.0/recent/",
"searchUrl":"/services/data/v61.0/search/",
"sobjectUrl":"/services/data/v61.0/sobjects/",
"userUrl":"/005x0000001SyyEAAS"
}
}
You can request Salesforce exclude portions of the context data that you dont need. To control the amount of data thats excluded, you
must implement your own Canvas.CanvasLifecycleHandler in Apex and provide a list of excluded context sections in your implementation
of excludeContextTypes().
Application
Environment
Links
Organization
User
SEE ALSO:
Client
Getting Context in Your Canvas App
Filtering CanvasRequest Context Data
Application
The Application object is a JSON-formatted object returned by the signed request in the Context object. The Application object contains
specific canvas app information obtained after youve added your app as a connected app in Salesforce from Setup by entering
Connected Apps in the Quick Find box, then selecting Connected Apps.
DescriptionField
The ID of the canvas app.applicationId
The access method of the canvas app. You specify this value when you expose the canvas app by
creating a connected app.
authType
The URL of the canvas app, for example:
http://instance.salesforce.com:8080/canvas_app_path/canvas_app.jsp.
canvasUrl
97
ContextObjects
DescriptionField
The internal name of the canvas app. You specify this value in the API Name field when you
expose the canvas app by creating a connected app.
developerName
The name of the canvas app.name
The Salesforce namespace prefix associated with the canvas app.namespace
An array that can contain one, two, or three of these values:options
HideHeaderHides the publisher header which contains the What are you working on?
text. This value is only used when the canvas app appears in the publisher.
HideShareHides the publisher Share button. This value is only used when the canvas app
appears in the publisher.
PersonalEnabledEnables the canvas app to be installed by users as a canvas personal
app.
The unique ID of the canvas app definition. Used internally.referenceId
The version of the canvas app. This value changes after you update and re-publish a canvas app in
an organization.
version
The following code snippet shows an example of the Application object.
"application":
{
"applicationId":"06Px000000003ed",
"authType":"SIGNED_REQUEST",
"canvasUrl":"http://instance.salesforce.com:8080/canvas_app_path/canvas_app.jsp",
"developerName":"my_java_app",
"isInstalledPersonalApp": false,
"name":"My Java App",
"namespace":"org_namespace",
"options":["HideShare", "HideHeader"],
"referenceId":"09HD00000000AUM",
"samlInitiationMethod":"None",
"version":"1.0.0"
}
SEE ALSO:
Context
Environment
The Environment object is a JSON-formatted object containing context information about the canvas app environment. This object
contains the Dimensions object, the Record object, the Version object, and parameters (if there are any) in the Parameters object.
98
ContextObjects
DescriptionField
The location in the application where the canvas app is currently being called
from. Valid values are:
displayLocation
ChatterThe canvas app was called from the Chatter tab.
ChatterFeedThe canvas app was called from a Chatter canvas feed
item.
MobileNavThe canvas app was called from the navigation menu.
OpenCTIThe canvas app was called from an Open CTI component.
PageLayoutThe canvas app was called from an element within a page
layout. If the displayLocation is PageLayout, one of the subLocation values
might be returned.
PublisherThe canvas app was called from a canvas custom quick action.
ServiceDeskThe canvas app was called from a Salesforce Console
component.
VisualforceThe canvas app was called from a Visualforce page.
NoneThe canvas app was called from the Canvas App Previewer.
The URL of the page in Salesforce where the user accesses the canvas app.
For example, if users access your canvas app by clicking a link on the Chatter
tab, this field contains the URL of the Chatter tab.
locationUrl
The sublocation in the application where the canvas app was called from
when the canvas app is loaded in a mobile device. The subLocation is related
subLocation
to the displayLocation. Valid values for this field when the displayLocation
is PageLayout are:
S1MobileCardFullviewThe canvas app was called from a mobile card.
S1MobileCardPreviewThe canvas app was called from a mobile card
preview. The user must click the preview to open the app.
S1RecordHomePreviewThe canvas app was called from a record detail
page preview. The user must click the preview to open the app.
S1RecordHomeFullviewThe canvas app was called from a page layout.
The default theme for the context organization.uiTheme
The following code snippet shows an example of the Environment object.
"environment":
{
"parameters":{},
"dimensions":
{
"clientHeight": "50px",
"clientWidth": "70px",
"height":"900px",
"width":"800px",
"maxHeight":"2000px",
99
ContextObjects
"maxWidth":"1000px"
},
"record": {
"attributes": {
"type": "Account",
"url": "/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id": "001xx000003DGWiAAO",
"Phone": "(555) 555-5555",
"Fax": "(555) 555-5555",
"BillingCity": "Seattle"
},
"displayLocation":"PageLayout",
"locationUrl":"https://salesforce.com/some/path/index.html",
"subLocation":"S1MobileCardFullview",
"uiTheme":"Theme3",
"version":
{
"api":"61.0",
"season":"SUMMER"
}
}
Dimensions
Record
Parameters
Version
SEE ALSO:
Context
Dimensions
Record
Parameters
Version
Dimensions
The Dimensions object is a JSON-formatted object containing context information about dimensions of the iFrame on which the canvas
app appears.
DescriptionField
The values of clientHeight are sent to the canvas app within
SignedRequest and can be used to set the height of the outermost div
clientHeight
element. This field is useful for setting the height of an app thats accessed
from a mobile device. The field can be referenced as
100
ContextObjects
DescriptionField
sr.context.environment.dimensions.clientHeight,
where sr is the parsed signed request JavaScript object.
The values of clientWidth are sent to the canvas app within
SignedRequest and can be used to set the width of the outermost div
clientWidth
element. This field is useful for setting the width of an app thats accessed
from a mobile device. The field can be referenced as
sr.context.environment.dimensions.clientWidth,
where sr is the parsed signed request JavaScript object.
The height of the iFrame in pixels.height
The width of the iFrame in pixels.width
The maximum height of the iFrame in pixels. Defaults to 2,000; infinite is
also a valid value.
maxHeight
The maximum width of the iFrame in pixels. Defaults to 1,000; infinite is
also a valid value.
maxWidth
The following code snippet shows an example of the Dimensions object.
"dimensions":
{
"clientHeight": "50px",
"clientWidth": "70px",
"height": "900px",
"width": "800px",
"maxHeight": "2000px",
"maxWidth": "1000px"
},
SEE ALSO:
Environment
User Interface Considerations
Record
The Record object is a JSON-formatted object that contains information about the object on which the canvas app appears. This could
be a standard object like Account or a custom object like Warehouse__c. If the canvas app doesnt appear on an object page or
in the publisher or feed associated with an object, then the Record object is empty.
This object contains the Attributes object.
DescriptionField
The ID of the related object. For example, if the canvas app appears on an
Account page, this field contains the AccountId.
Id
101
ContextObjects
If the canvas app appears on a Visualforce page through use of the <apex:canvasApp> component, and that Visualforce page is
associated with an object (placed on the page layout, for example), you can use the entityFields attribute on the component to
return specific fields or all fields from the related object.
The following code snippet shows an example of the Record object returned from a canvas app that appears on an Account page. In
this example, the Phone, Fax, and BillingCity fields were specified in the entityFields attribute.
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO",
"Phone":"(555) 555-5555",
"Fax":"(555) 555-5555",
"BillingCity":"Seattle"
}
Attributes
Record Object Examples
These code examples demonstrate how the Record object contains different information depending on whether your canvas app
appears in the publisher or the feed.
SEE ALSO:
Environment
Attributes
Record Object Examples
Returning Fields in the Record Object
Attributes
The Attributes object is a JSON-formatted object that contains information about the object on which the canvas app appears.
DescriptionField
The object that the canvas app is associated with. This value could be a
standard object like Account or a custom object like Warehouse__c.
If the canvas app appears in the publisher, then the type is the name of the
associated object. For example, CollaborationGroup or Account.
type
If the canvas app appears in a user feed or the feed associated with an object,
then the type is FeedItem.
The URL of the associated object. The format of the URL is the same as the
REST API resource for the given record.
url
102
ContextObjects
The following code snippet shows an example of the Attributes object.
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO"
}
SEE ALSO:
Record
Record Object Examples
These code examples demonstrate how the Record object contains different information depending on whether your canvas app
appears in the publisher or the feed.
Canvas App in the Publisher
If your canvas app appears in the publisher, the Record object contains different information depending on whether the publisher
appears on a user record, a group record, or an object record.
User Record
The Record object Id is the User.Id and the Type is User.
"record":{
"attributes":{
"type":"User",
"url":"/services/data/v61.0/sobjects/User/001xx000003DGWiABC"
},
"Id":"001xx000003DGWiABC"
}
Group Record
The Record object Id is the CollaborationGroup.Id and the Type is CollaborationGroup.
"record":{
"attributes":{
"type":"CollaborationGroup",
"url":"/services/data/v61.0/sobjects/CollaborationGroup/001xx000003DGWiXYZ"
},
"Id":"001xx000003DGWiXYZ"
}
Object Record
The Record object Id is the object Id and the Type is the object name, for example, Account.
"record":{
"attributes":{
"type":"Account",
"url":"/services/data/v61.0/sobjects/Account/001xx000003DGWiAAO"
},
103
ContextObjects
"Id":"001xx000003DGWiAAO"
}
Canvas App in the Feed
If your canvas app appears in the feed, the Record object always contains the feed item information whether the feed is on a user record,
a group record, or an object record.
The Record object Id is the FeedItem.Id and the Type is FeedItem.
"reoord":{
"attributes":{
"type":"FeedItem",
"url":"/services/data/v61.0/sobjects/FeedItem/001xx000003DGWiAAO"
},
"Id":"001xx000003DGWiAAO"
}
Parameters
The Parameters object is a JSON-formatted object containing context information specified by the developer. The Parameters object is
specified in a Visualforce page by using the parameters tag in the apex:canvasApp component, or in a Chatter canvas feed
item by using the parameters variable when creating the feed item.
The following code snippet shows an example of the Parameters object.
"parameters":
{
"inventoryStatus":"Picked",
"stockPrice":"12.99",
"count":2,
"address":{"street":"1 Market", "city":"San Francisco", "state":"CA"}
}
SEE ALSO:
Environment
apex:canvasApp Component
Version
The Version object is a JSON-formatted object containing context information about the version of Salesforce running on the server.
DescriptionField
The API version of the server.api
The season of the release running on the server.season
The following code snippet shows an example of the Version object.
"version":
{
104
ContextObjects
"api": "61.0",
"season": "WINTER"
}
SEE ALSO:
Environment
Links
The Links object is a JSON-formatted object containing URLs that can be helpful when integrating your canvas app. For example, use
the enterpriseUrl to make calls into Salesforce using the enterprise WSDL.
Note: The links that are listed here are the most commonly used links. They can be helpful when youre building the REST endpoints
for your canvas app. For a complete list of links and related functionality, see the Lightning Platform REST API Developers Guide
and the Connect REST API Developer Guide.
DescriptionField
URL to return Chatter feed items for the context organization. This link will
still work for integrations created prior to API version 61.0, because the link
only points to functionality within API versions 31.0 and earlier.
chatterFeedItemsUrl
URL to return Chatter feeds for the context organization. This link will still
work for integrations created prior to API version 61.0, because the link only
points to functionality within API versions 31.0 and earlier.
chatterFeedsUrl
URL to return Chatter groups for the context organization.chatterGroupsUrl
URL that returns Chatter users for the context organization.chatterUsersUrl
URL to make API calls back to Salesforce using the enterprise WSDL.enterpriseUrl
URL of the login server for the instance the context user is logged into. Used
internally.
loginUrl
URL to make calls to the Metadata API.metadataUrl
URL to make API calls back to Salesforce using the partner WSDL.partnerUrl
URL to issue a SOQL query.queryUrl
URL to access recent items.recentItemsUrl
URL to return a list of REST API resources.restUrl
URL to issue a SOSL search.searchUrl
URL that retrieves metadata or data from Salesforce objects.sobjectUrl
URL for the context user.userUrl
105
ContextObjects
The following code snippet shows an example of the Links object.
"links":
{
"chatterFeedItemsUrl":"/services/data/v31.0/chatter/feed-items",
"chatterFeedsUrl":"/services/data/v31.0/chatter/feeds",
"chatterGroupsUrl":"/services/data/v61.0/chatter/groups",
"chatterUsersUrl":"/services/data/v61.0/chatter/users",
"enterpriseUrl":"/services/Soap/c/61.0/00Dx00000001hxy",
"loginUrl":"https://login.salesforce.com",
"metadataUrl":"/services/Soap/m/61.0/00Dx00000001hxy",
"partnerUrl":"/services/Soap/u/61.0/00Dx00000001hxy",
"queryUrl":"/services/data/v61.0/query/",
"recentItemsUrl":"/services/data/v61.0/recent/",
"restUrl":"/services/data/v61.0/",
"searchUrl":"/services/data/v61.0/search/",
"sobjectUrl":"/services/data/v61.0/sobjects/",
"userUrl":"/005x0000001SyyEAAS"
}
Available Links and OAuth Scopes
Links that the canvas app can use depend on what OAuth scopes are selected when you create the connected app.
DescriptionScope
Access your basic information
userUrl
loginUrl
Access and manage your data
enterpriseUrl
metadataUrl
partnerUrl
queryUrl
recentItemsUrl
restUrl
searchUrl
sobjectUrl
Access and manage your Chatter data
chatterFeedItemsUrl
chatterFeedsUrl
chatterGroupsUrl
chatterUsersUrl
All linksFull access
SEE ALSO:
Context
106
ContextObjects
Organization
The Organization object is a JSON-formatted object containing context information about the organization in which the canvas app is
running.
DescriptionField
If multi-currency is enabled for the context organization, then the context
users currency is returned. Defaults to the corporate currency if not set. If
currencyIsoCode
multi-currency is disabled for the context organization, the currency for the
corporate currency locale is returned.
Indicates whether the context organization uses multiple currencies (true)
or does not (false).
multicurrencyEnabled
The Salesforce namespace prefix associated with the canvas app.namespacePrefix
The name of the context organization.name
The ID of the context organization.organizationId
The following code snippet shows an example of the Organization object.
"organization":
{
"currencyIsoCode":"USD",
"multicurrencyEnabled":true,
"name":"Edge Communications",
"namespacePrefix":"org_namespace",
"organizationId":"00Dx00000001hxyEAA"
}
SEE ALSO:
Context
User
The User object is a JSON-formatted object containing context information about the current user. This information can be used within
the canvas app (for example, to display the users name) or to make subsequent calls to retrieve additional information (for example, to
get role information for the current user).
DescriptionField
For the context user, indicates whether user interface modifications for the
visually impaired are on (true) or off (false).
accessibilityModeEnabled
Returns the context user's default currency code for multiple currency
organizations or the organization's currency code for single currency
organizations.
currencyISOCode
The context users email address.email
107
ContextObjects
DescriptionField
The context user's first name.firstName
The context user's full name. The format is: Firstname Lastname.fullName
For the context user, indicates whether the user is in an Experience Cloud
site (true) or not (false).
isDefaultNetwork
Important: Canvas apps are not supported for guest users. They are
supported on Experience Cloud sites only for logged in users.
The context users language. String is 2-5 characters long. The first two
characters are always an ISO language code, for example fr or en. If the
language
value is further qualified by country, then the string also has an underscore
(_) and another ISO country code, for example US or UK. For example,
the string for the United States is en_US, and the string for French Canadian
is fr_CA.
The context user's last name.lastName
The context users locale.locale
The ID of the context users currently logged-in Experience Cloud site.networkId
The ID of the profile associated with the role currently assigned to the context
user.
profileId
The URL for the photo of the context users profile photo if Chatter is enabled.
The URL is updated every time a photo is uploaded and reflects the most
profilePhotoUrl
recent photo. URL returned for an older photo is not guaranteed to return a
photo if a newer photo has been uploaded. Always query this field for the
URL of the most recent photo.
The URL for a thumbnail of the context users profile photo if Chatter is
enabled. The URL is updated every time a photo is uploaded and reflects the
profileThumbnailUrl
most recent photo. URL returned for an older photo is not guaranteed to
return a photo if a newer photo has been uploaded. Always query this field
for the URL of the most recent photo.
The ID of the context users currently assigned role.roleId
The URL of the context users currently logged-in Experience Cloud site.siteUrl
The URL prefix of the context users currently logged-in Experience Cloud
site.
siteUrlPrefix
The context users time zone.timeZone
The context users ID.userId
The context users login name.userName
The type of user license assigned to the profile associated with the context
user.
userType
108
ContextObjects
The following code snippet shows an example of the User object.
"user":
{
"accessibilityModeEnabled":false,
"currencyISOCode":"USD",
"firstName":"Sean",
"fullName":"Sean Forbes",
"isDefaultNetwork":false,
"language":"en_US",
"lastName":"Forbes",
"locale":"en_US",
"networkId":"0DBxx000000001r",
"profileId":"00ex0000000jzpt",
"profilePhotoUrl":"/profilephoto/005/F",
"profileThumbnailUrl":"/profilephoto/005/T",
"roleId":null,
"siteUrl":"https://MyDomainName.my.salesforce.com/",
"siteUrlPrefix":"/mySite",
"timeZone":"America/Los_Angeles",
"userId":"005x0000001SyyEAAS",
"userName":"[email protected]",
"userType":"STANDARD"
}
SEE ALSO:
Context
Controller
If your Visualforce page contains a canvas app, you can use methods in the Controller object to publish an event that the canvas app
subscribes to. It contains these methods:
DescriptionSignatureMethod
Used to publish an event that the canvas app
subscribes to. The target parameter is
publish(String name, Object
payload [, String[] target])
publish
optional. It can contain a single canvas app
name or an array of canvas app names.
Used by a Visualforce page to resize a canvas
app iFrame.
resize(String height, String
width, String target)
resize
Used by a Visualforce page to subscribe to
events that the canvas app might publish.
subscribe(Subscriber event)subscribe
109
ControllerObjects
DescriptionSignatureMethod
Used by a Visualforce page to unsubscribe to
parent events that the canvas app might publish.
unsubscribe(Unsubscriber event)unsubscribe
SEE ALSO:
Using Events between a Visualforce Page and a Canvas App
SignedRequest
SignedRequest
Canvas provides a SignedRequest object that has methods you can use to work with signed requests.
DescriptionSignatureMethod
Used to verify and decode a signed request;
returns a CanvasRequest Java object.
public static CanvasRequest
verifyAndDecode(String input,
String secret) throws
SecurityException
verifyAndDecode
Used to verify and decode a signed request;
returns the CanvasRequest data in a JSON string.
public static String
verifyAndDecodeAsJson(String
input, String secret) throws
SecurityException
verifyAndDecodeAsJson
SEE ALSO:
CanvasRequest
Verifying and Decoding a Signed Request
Requesting a Signed Request
110
SignedRequestObjects
CHAPTER 13 Canvas Limits
Because Canvas runs in a multitenant environment, limits are enforced to ensure protection of shared resources.
LimitDescription
50Number of canvas apps per user that can be displayed on the
Chatter tab. Only the first 50 canvas apps are displayed (sorted
alphabetically).
5,000 per Salesforce full user license in the org. This limit is shared
across all users in the org. Requests from guest users dont count
against this limit.
This limit tracks each Canvas app reload and signed request calls.
Other API calls from the Canvas app are counted against the normal
Number of Canvas calls per day per user (24hour period)
org API request limit. When you call a SignedRequest method, two
calls are madeone for the method and one for internal logging.
100
Heroku accounts have their own limits on the number of calls you
can make.
Heroku Quick Start calls per day per user
SEE ALSO:
Introducing Canvas
Quick Start (currently unavailable)
Quick StartAdvanced
111
INDEX
A
apex:canvasApp component 56
Application object 97
Associating a CanvasLifecycleHandler with an app 85
Aura
canvas app code examples 64
Authentication
OAuth 36
refresh signed request 35
SAML SSO 40
signed request 29, 35
B
Browsers supported 4
C
Canvas app process
overview 6
Canvas app user flow
OAuth 37
signed request 30
canvas apps 80
Canvas apps
events 47
in a mobile card 66
in a page layout 66
in the publisher 69
listening for Streaming API events 51
resizing 44, 60
Visualforce 60
where they appear in the user interface 3
where they can appear in a page layout 67
Canvas apps in Salesforce app
set the location 78
Canvas apps in the publisher
create the action manually 70
set the location and create the action 70
canvas personal apps
distribution of 9
how users install 9
revoking token for 11
uninstalling 11
Canvas Personal Apps
about 8
Canvas scenarios 3
Canvas SDK
hosted on Salesforce server 28
publisher events 71
CanvasLifecycleHandler
Associating a CanvasLifecycleHandler with an app 85
Controlling canvas app behavior 86
Creating a new CanvasLifecycleHandler 85
Distributing your CanvasLifecycleHandler class 89
Filtering CanvasRequest context data 86
onRender() 86
Presenting user error messages 87
Testing your CanvasLifecycleHandler implementation 88
CanvasRequest
object 91
CanvasRequest object 91
Chatter Feed
context considerations when exposing a canvas app in the
feed 75
Client object 94
Code examples
events, creating an event 49
events, subscribing to an event 49
events, unsubscribing from an event 50
exposing canvas app on a Lightning page 64
exposing canvas app on a Visualforce page 55
getting context 40
OAuth flow 39
publishing a canvas app in Visualforce by calling publish 61
resizing, automatically resizing a canvas app by calling
autogrow 44
resizing, explicitly resizing a canvas app by calling resize 45
resizing, explicitly resizing a canvas app in a Visualforce page
by calling resize 62
resizing, getting the size of a canvas app by calling size 46
resizing, handling orientation changes by subscribing to the
orientation event 47
resizing, subscribing to events by calling subscribe 62
resizing, subscribing to parent events by calling subscribe
46
resizing, unsubscribing from events by calling unsubscribe
63
Streaming API, creating a Streaming API event 51
Streaming API, unsubscribing from a Streaming API event
by calling unsubscribe 53
verifying and decoding a signed request 31
XHR, getting a list of Chatter users 41
112
Code examples (continued)
XHR, posting to a Chatter feed 42
Context
Application object 97
Client object 94
Dimensions object 100
getting from canvas app 40
Organization object 107
Parameters object 104
User object 107
Controller 109
Controlling canvas app behavior 86
Creating a new CanvasLifecycleHandler 85
Cross-domain XHR 41
Customizing app lifecycle
Associating a CanvasLifecycleHandler with an app 85
Controlling canvas app behavior 86
Filtering CanvasRequest context data 86
Presenting user error messages 87
D
Debug 53
Dimensions object 100
Distributing your CanvasLifecycleHandler class 89
E
Events
considerations 48
creating, code example 49
subscribing to, code examples 49
unsubscribing from, code examples 50
Events code examples
creating an event 49
subscribing to an event 49
unsubscribing from an event 50
F
Filtering CanvasRequest context data 86
L
Limits 111
M
Mobile card
canvas apps, adding to 66
N
navigation methods 80
O
OAuth
initiating 39
OAuth authentication 36
Organization object 107
Orientation
handling in your canvas app 47
P
Page layout
add a canvas app 67
canvas apps, adding to 66
canvas apps, where they can appear 67
Parameters object 104
Presenting user error messages 87
Process for creating a canvas app 6
Publisher
canvas app access considerations when exposing a canvas
app in the publisher 73
canvas apps in 69
context considerations when exposing a canvas app in the
publisher 72
Publisher events 71
Publishing code examples
publishing a canvas app in Visualforce by calling publish 61
Q
Quick start
create the app 13
introduction 12
prerequisites 13
Quick startadvanced
clone the hello world project 17
create the canvas app 19
deploy the hello world Web app to Heroku 22
install the canvas app 25
introduction 16
package the canvas app 24
prerequisites 17
run the Web app locally 18
update the canvas app 23
upload the canvas app package 25
R
Resizing 44, 60
Resizing code examples
automatically resizing a canvas app by calling autogrow 44
explicitly resizing a canvas app by calling resize 45
113
Index
Resizing code examples (continued)
explicitly resizing a canvas app in a Visualforce page by calling
resize 62
getting the size of a canvas app by calling size 46
subscribing to events by calling subscribe 62
subscribing to parent events by calling subscribe 46
subscribing to the orientation event 47
unsubscribing from events by calling unsubscribe 63
S
Salesforce app
access considerations when exposing a canvas app in
Salesforce app 79
canvas apps in 77
context considerations when exposing a canvas app in
Salesforce app 78
icon considerations when exposing a canvas app in
Salesforce app 80
SAML SSO 40
SDK Objects 91
select tag in a canvas app 53
sfdc.streamingapi event 51
Signed request
verifying and decoding 31
Signed request authentication 29, 35
SignedRequest
object 110
SignedRequest object 110
Streaming API 51
Streaming API code examples
unsubscribing from a Streaming API event by calling
unsubscribe 53
Streaming API event 51
Supported browsers 4
T
Testing your CanvasLifecycleHandler implementation 88
U
User object 107
User permissions required 5
V
Visualforce
apex:canvasApp component 56
canvas app code examples 55
considerations when exposing a canvas app 56
W
Where canvas apps appear 3
X
XHR 41
XHR code example
getting a list of Chatter users 41
posting to a Chatter feed 42
114
Index