Using external library in Zapworks studio script

Hi All,

I looked through all the code references on the Zapworks docs but don’t see and answer to my issue. Can someone provide me with the basic boiler plate code to reference an outside library. In my case I want to use Zapworks Studio World tracking to pull in various 3d objects by user GLTFLoader.js. I know how to do this if I was writing vanilla JS for a web app but the scripts in Zapworks studio don’t work the same way. I know I have to us an import and reference the absolute URL for GLTFLoader.js.

Any help appreciated.

ZapWorks Studio doesn’t support external scripts I’m afraid.

I assume you’re talking about GLTFLoader.js from the three.js project - that’s built to load glTF files into a three.js scene and so wouldn’t work in Studio anyway (we have our own custom renderer and do not use three.js).

In ZapWorks Studio you can actually load glTF files from the web without needing any script. On an Object node you can just set the type to a URL:
symbol.nodes.myobject.type(''); - the object will emit “notready” whilst it’s loading and then “ready” when it’s done. We’d recommend using the glb format which packs all the data and textures in one file.

The other approach is to use our Universal AR for three.js SDK which allows you to use three.js and all the external scripts you want, but you won’t be able to use the visual editing capabilities of Studio in that case.

1 Like

Thanks for getting back to me Simon. I used the code you suggestion to load a glb file but everytime I test it, it fails. Not sure what I’m missing. Please take a look at the screen shot.

Regarding three.js: The Instant World Tracking is no where near as stable as the World Tracking in Studio. I actually tested UAR with the Unity SDK, three.js SDK and Playcanvas SDK and in all cases the Instant World Tracking was very unstable. Objects would not “stick” to the spot they were placed the way they do using World Tracking in Studio. I did use the #beta version of the SDK to get access to the advanced Instant tracking. I actually would prefer to use UAR with the Unity SDK as I’m an experienced C# dev and I am much more comfortable with straight-up coding instead of using actions in Studio. But again the faulty World tracking is a show stopper.


Hi Simon,

Just following up. Did you see my last post?


Using external libraries in Studio is very much possible, it’s just not documented, and not everything works.

Generally speaking, anything that touches the canvas won’t work. Particles libraries that shows beautiful stuff on the screen won’t work, anything visual won’t work, because Studio has full control over the canvas. If it’s a library that just does math or communicate with a database for example, it will work though. There are certain libraries out there, like popmotion, that does animation purely with math, no canvas stuff involved. These libraries very much work. You can even use some libraries to add basic physics behavior.

Here’s an example code snippet

declare const document;
(async () => {
await addLibrary(“”);
const world = Physics({sleepDisabled: true});

let physicsPlane = Physics.body('rectangle', {
    x: plane.position()[0], // x-coordinate
    y: plane.position()[1], // y-coordinate
    width: plane.scale()[0],
    height: plane.scale()[1]


function addLibrary(library) {
let head = document.getElementsByTagName(‘head’)[0];
let script = document.createElement(‘script’);
script.type = ‘text/javascript’;
script.src = library;

return new Promise((resolve, reject) => {
    script.onload = () => resolve("loaded");
    script.onerror= () => reject("error");


“declare const document” tells Studio that “document” is a variable that exists and is there, even though Studio thinks it doesn’t exist(or rather, Studio wants you to think that it doesn’t exist). Without the “declare const document” you will get an error saying that “document” doesn’t exist. What we’re doing here is getting access to a variable that’s already there but hidden from us. Don’t use “let document” instead. If you do that, you will hide the document object and just use a normal variable that happens to be called “document”.


Hi Simon,

Sorry to bug you but it would really help a lot to resolve this issue on my project. Client is putting some pressure on me.

Can you take a look at my screen shot and what I wrote in the prior post and let me know what you think?


If you’re using ZapWorks Studio’s world tracking then I assume you’re using the Zappar app to view the content? Which platform are you using for testing?

I’ll try to take a look but I can’t provide dedicated support, I pop up occasionally in the forum with hopefully helpful responses, but my day job at Zappar is working on things like improving the quality of our World Tracking for WebAR implementation. Our dedicated support team are brilliant and can provide individual support if you’re on a Pro plan.

On the forum we have fantastic community members like @marks who are also super helpful with answering questions from other users.

As a non-ZapWorks suggestion - if installing an app is acceptable for this project then could you build a dedicated app for this in Unity and use their AR Foundation wrappers around ARKit / ARCore? If you’re more comfortable in Unity that might be the easiest route to test and debug.

1 Like

I am using the Zappar IOS app and World Tracking via ZapWorks Studio. This is the best combo for my client’s use case. ARFoundation is a no go because of the lack of WebAR. UAR is a no go because Instant World Tracking doesn’t perform as well as ZapWorks Studio World Tracking.

I don’t have a pro plan (not in my client’s budget) and I’m not sure dedicated support is needed here as IMHO, my question is very straight-forward. I just want someone (anyone in the community) to look at my screen shot that shows, essentially, one line of code in ZapWorks Studio based on the code you suggested in your response to my initial question regarding GLTFLoader.js. Despite writing exactly what you suggested the app is not working and I’m hoping someone can point out why?

I totally understand the point you made about your full time job at Zappar being an engineer and not answering questions on the forums. So, given knowing this now, I won’t expect you necessarily reply.

However, to be fair and with all due respect, I might point out that it is not unreasonable to suppose that if you initially answered my question on the forum (unsolicited toward you), I could be forgiven to expect you might be available to clarify your initial response. :slight_smile:

Yes, because I posted a response initially I did take a look, and there was nothing obviously different from my suggestion in the screenshot. I was planning to take a look into the specifics a bit more, in terms of that exact .glb URL etc, but wanted to know your target platform before doing that.

My initial answer was more to point you in the right direction, not something I’d specifically tested recently, and it looks like there may be a bit more manual setup needed in terms of materials etc.

I’ll dig into what’s going on with that URL on iOS now.

It’s always best to post a zpp if you can; saves anyone looking into your issue from setting up their own test project from scratch and makes it easier for you to incorporate any fixes.

Here’s a demo zpp which does show it working with a demo glb model:
modeltest.zpp (3.3 MB)

One thing that is required for assets from the web is to ensure the CORS headers are set to allow cross-origin access. I think iOS checks for those too by default in its HTTP classes, which may have been what was going wrong before. The URL in your screenshot is now a 404 error so I wasn’t able to confirm if that would explain your issue.

I managed to grab a copy of your model yesterday, and I uploaded it to the same bucket as the duck demo model. It sort-of works, but the materials don’t load properly and it sometimes crashes the app.

It’s best to keep the GLBs pretty standard (your one has vertex colours defined as uint16 components, which is pretty unusual and probably explains the incorrect materials and perhaps the crash too). It’s also a big file for the amount of geometry - worth also checking the texture resolution is not much higher than required.

Hope that helps!

Thanks Simon. Really appreciate you taking the time to send this file. Helps a lot!