Fetching project files

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 always work consistently across platforms.

Why some platforms are different

Normally code like fetch("myfile.txt") will make a relative request to a resource in the same folder on the server. Usually this works in preview mode because there is a Service Worker that intercepts the request. Note 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. Therefore in preview mode this request will not actually fetch https://preview.construct.net/myfile.txt like it normally would (and which would normally return 404 Not Found, since nothing is uploaded); the Service Worker intercepts and responds with the local file. However this may not work in all circumstances for all types of media that may be fetched.

A more significant problem is that several types of exports don't actually run on a web server. In particular Android apps internally run on a file: scheme, which has strict security restrictions which prevent your app being able to fetch local files normally.

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 to the web, 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.

In mobile apps where the fetch might not normally work, 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. This ensures it works even in non-web exports where fetches might not normally work.

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.

Construct 3 Manual 2021-02-03