Construct 3 icon

Construct 3

Documentation

Fetching project files

Published 7 Apr, 2020
515 words
~2-3 mins

Fetching local project files in scripting requires some adjustment to your code. Suppose you import myfile.txt to the Files folder in the Project Bar. Ordinarily fetch("myfile.txt") would be able to retrieve that. However this does not work in preview mode.

Why preview mode is different

Previewing your project in Construct does not upload it anywhere - it runs entirely locally. This is to ensure it's fast, private, and works offline.

If you try to run code like fetch("myfile.txt") in preview mode, it will actually make a request for it to the Construct server. Since nothing from your project has been uploaded anywhere, it will return 404 Not Found.

Getting the correct URL

To solve this, Construct provides a method to convert the URL in to one that you can directly fetch. This is done with the getProjectFileUrl() method of IAssetManager.

An example on using it is shown below.

async function OnBeforeProjectStart(runtime)
{
	// Get the correct URL to fetch
	const textFileUrl = await runtime.assets.getProjectFileUrl("myfile.txt");

	// Now fetch that URL normally
	const response = await fetch(textFileUrl);
	const fetchedText = await response.text();

	// ... do something with fetchedText ...
}

This pattern should be used for loading any local project file by any means, such as setting the src of a new Image to load an image file; creating a Web Worker from a script file; using XMLHttpRequest instead of fetch; and so on. First use getProjectFileUrl() to look up the real URL to retrieve, and then proceed to load it normally like you would have otherwise, but with the adjusted URL.

Some more details

Once you export your project, you can once again fetch project files like "myfile.txt" directly, since the project is now uploaded to a web server and that URL will work as expected. So once exported, getProjectFileUrl() just returns the same URL you gave it since nothing needs to be changed.

A similar problem applies on some export platforms too, such as in mobile apps. On these platforms your app is also running locally instead of on a web server. It's the same problem with the same solution, so using this code ensures it works across all platforms as well. Construct automatically detects if the given URL will work, and returns that if so, else substitutes it for a different URL that can be loaded instead.

What URL does Construct use instead? When it has to substitute the URL, it will use a blob URL instead. This is a randomly generated URL that begins with blob:, e.g. blob:https://preview.construct.net/3c1ca690-91cc-4120-bf6a-ddc02d8a22a3. This is basically a URL that refers to a local file, which means it can be fetched as if it was on the Internet, but it actually just loads something on the same device. Internally Construct represents local files with Blobs, and these URLs are generated by URL.createObjectURL(). In some cases you may see these types of URLs being shown in developer tools or while debugging, and it just means it's loading a local resource instead of getting something over the Internet.