Running Playcanvas inside another page without iframe ( In-APP Implementations )


I have a somewhat unique circumstance Im trying to solve to serve Playcanvas as In-App rich media. First, it works flawlessly on IOS but sadly our network is based on coverage and quality and Android seems to show a problem so unless we can solve for Android, we cant move forward with Playcanvas as awesome as it is. After many, many, many rounds of testing, we believe we have pinned the issue down to the iframes in the Android WebView do not have the ability to ‘grab’ a webgl context. Our debug code is trying to find all the lowest/oldest versions of webgl on the page when the ad unit delivers and we can see that it gets a context fine in the parent page but when we add that code to the Playcanvas start.js to test for context availability, we get the UnsupportedBrowser case and the exception name of ContextCreationError and no values for any of the contexts we attempt to detect.

On a side aspect of the test, we used Goo Create as a control mechanism since it also requires webGL. In the control testing we have no issues, meaning that Goo’s technology runs fine. The twist is that the Goo technology is not running in a frame, so, it is able to ‘grab’ a context in the parent page where there seem to be no issues with webGL access. This brings me to my question:

Is it possible to load the Playcanvas unit into a page without it using an iframe or being its own page of distinct content? By that I mean, is it possible to wrap the ‘boot’ of the unit in a script that adds all its necessary resources to the page its running in or does Playcanvas have an architecture that specifically requires it to run in a frame ( scope bleed, memory management, etc )?

I have worked with some rich media vendors wherein their object architecture requires their resources to be framed to prevent problems

What we want to do is load the whole thing into the main page of our ad, but it also has to load into a specific container in order to allow the rest of the ad to be seen.

If anyone has tried this or has insight into gotchas and pitfalls it would greatly appreciated. Im really pushing for Playcanvas and have demoed how great it is and we were all pumped until we hit this edge-case that sadly makes it a non starter for us if we cant solve.

Here is where im sandboxing this build for testing, you can check the start.js to see if my debug method is accurate:

hosted customized playcanvas


Wait, the link you providing is a PlayCanvas instance running inside the page itself, not in an iframe, right? Specifically, __start__.js creates a canvas element and adds it to the document root.

Couldn’t you just modify those first few lines in __start__.js to use an already existing canvas or create one and append it inside whatever container you want?

I’ve done something similar for a game for the last Ludum Dare, but what I couldn’t figure out was how to cleanly destroy the PlayCanvas instance.

I think you can download the resources and put them on your own server, and then use the playcanvas engine to start your game.

Some thing like:

var configUrl = '';
var sceneUrl = '';
var app = new pc.Application(canvas, {});
app.configure(configUrl, function (err) {
  app. loadScene(sceneUrl, function (err) {

Note: loadScene is internal api, this way is a little hack.

I think I understand what you are saying. That makes sense and ‘feels right’ – move the setup code to the parent where the webGL is available if that doesnt work just target a canvas living in the parent. Good thinking!

I’ll let you know the results.

Thanks very much.

Thank you both again for your help,

I am getting closer. I havent tested the In-App cases yet but one thing that seems to be wonky in the non In-App cases are the animations and interactivity. I’m in the process of setting up a test page that will allow you to interact and poke it with a stick, but this is a screen cast of the difference as well as the start script im using:


start script

page showing it functioning as expected when nothing else happening in the page

It seems like something about the way the 3D loads into the page is not properly handling the various game scripts or not properly binding the events.

Let me know if you have any suggestions to try. If I am able to get this all running as expected I will provide the solution ( code and documentation ) for anyone else who runs into trouble with running in an Iframe.


I think you should check your onMouseMove method by your own.
Print the movement data into console, and see what’s wrong with it…

Its a bit difficult to see in the recording, my guess is similar to @scarlex, the mouse/touch events are probably restricted to the canvas and not the page.

You can potentially get round this by listening to the window mouse and touch events over the internal PlayCanvas ones.

Sorry about the quality of the video. I appreciate you giving it a look.

I also think its related to event dispatching in that preview program. I did some more testing and happily can report that despite that preview page acting funny, the actual In-App execution and Mobile Web executions and Desktop with mobile simulator executions all worked as expected. So Im confident that this other platform has some bugs that are interacting with PlayCanvas. Equally confident our break case is solved which means we can keep PlayCanvas!!!

Thanks for the insights! I’ll let you know where I end up and post any useful code.

1 Like


To sum up, We needed to run inventory mobile in-App which uses SDK’s to allow app publishers to integrate ads via various webview flavors. In many cases, the SDK’s limit IFRAMEs due to security concerns and additionally limit webGL for both security and hardware drain reasons. As a result, in a basic poll we found that PlayCanvas wouldnt load across our network while in an IFRAME. As a result we worked out a self hosting solution that allows us to implement PlayCanvas in a Div with some namespacing limitations.

Our solution involves:

  • Getting the web download from the publish area
  • uploading that download to your hosting area ( we use a CDN )
  • unzipping the archive somewhere on that host
  • Modify the start script to reduce the dependency on the index page
    • the global vars setup in the index page
  • Modify the start script to have it locate itself in the page
    • we added an extra query string with the scene the script should load so that a loop across the scripts object can find it using the config and then target its parent element as the container for the canvas
  • Modify the start script to configure the app to run with a scene based set of ids

Ive included the prototype start script to see how we tailored it. Its not very clean but anyone who knows what the above means should be able to understand what is and isnt debug code.

Thanks again for the help.

1 Like