The Instructure Community will enter a read-only state on November 22, 2025 as we prepare to migrate to our new Community platform in early December. Read our blog post for more info about this change.
Found this content helpful? Log in or sign up to leave a like!
Hello community. I am building a simple LTI 1.1 Application. The LTI tool is delivered and authenticated via AWS Lambda functions, and the app itself consists of some basic HTML and javascript with a single page at a single endpoint. The purpose of the LTI is to serve as a time on page tracker use a simple timed Javascript timer function with an alert that asks "are you still learning" and logs the duration of time on a page to a backend database for training compliance purposes.
I want the LTI to be selected in the rich content editor, and I want it to be embedded within the page as an iframe. I have been able to get the LTI tool into the rich content editor using XML parameters, but it appears as a modal and I do not know how to get it to appear as an iframe. Could someone perhaps offer guidance about how to get the LTI tool to appear within an iframe by selecting within the rich content editor? Thanks!
The goal here is to use the rich content editor to embed an LTI that is able to pass back the userid and pageid parameters.
Anyone with thoughts on this? The IMS documentation is really difficult to decipher. I'm build a flask LTI 1.1 app and really stuck at this point. Is it easier to just switch over to 1.3 or is there a reasonably manageable way to do this with 1.1?
For LTI 1.1 take a look at: https://canvas.instructure.com/doc/api/file.content_item.html LTI 1.1 Content-Item Process.
basically, the key point is that you need 2 lti endpoints:
1. for the LTI content embed selection - this is the one that you see in the popup of the editor. It can specify for canvas different resources to load, It should return the content that you want canvas to embed on the page/activity. The one that you want is something like:
{
"@context": "http://purl.imsglobal.org/ctx/lti/v1/ContentItem",
"@graph": [
{
"@type": "LtiLinkItem",
"url": 'https://your.basic.lti.launch.url',
"mediaType": "application/vnd.ims.lti.v1.ltilink",
"text": "",
"placementAdvice": {
"presentationDocumentTarget": "iframe",
"displayWidth": 640,
"displayHeight": 360,
}
}
]
};
2. Your basic lti launch endpoint - this is the one that is going to be embedded as iframe on the activity/page, with no popup and should be the page tracker you want.
For more details: http://www.imsglobal.org/specs/lticiv1p0/specification
At step 1 the result should be submitted back to canvas as a forum. Some LMSs requires that the submitted result must be signed with oath1 signature, some accept unsigned.
If you are familiar with JSX maybe this code snippet can help (it has signed and unsigned versions):
<form action={this.returnUrl} method="post" encType="application/x-www-form-urlencoded" ref={(el) => this.itemSelectForm = el as HTMLFormElement}>
{signedData ? [
<input type="hidden" name="lti_message_type" value={signedData.lti_message_type} />,
<input type="hidden" name="lti_version" value={signedData.lti_version} />,
<input type="hidden" name="content_items" value={signedData.content_items} />,
signedData.data ? <input type="hidden" name="data" value={signedData.data} /> : null,
<input type="hidden" name="oauth_version" value={signedData.oauth_version} />,
<input type="hidden" name="oauth_nonce" value={signedData.oauth_nonce} />,
<input type="hidden" name="oauth_timestamp" value={signedData.oauth_timestamp} />,
<input type="hidden" name="oauth_consumer_key" value={signedData.oauth_consumer_key} />,
<input type="hidden" name="oauth_callback" value={signedData.oauth_callback} />,
<input type="hidden" name="oauth_signature_method" value={signedData.oauth_signature_method} />,
<input type="hidden" name="oauth_signature" value={signedData.oauth_signature} />
]
: [
<input type="hidden" name="lti_message_type" value="ContentItemSelection" />,
<input type="hidden" name="lti_version" value="LTI-1p0" />,
<input type="hidden" name="content_items" value={contentItems || ''} />,
this.contentData ? <input type="hidden" name="data" value={this.contentData} /> : null,
]}
</form>Hope it helps.
Community helpTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign inTo interact with Panda Bot, our automated chatbot, you need to sign up or log in:
Sign in