How To Serve Unity3D WebGL From AWS S3 Via AWS CloudFront

Lately I had a tough time to figure out how to serve a Unity3D WebGL export via AWS CloudFront from an AWS S3 origin after updating to Unity3D 2020.01 with it’s new WebGL loader. I don’t describe how to connect AWS CloudFront to serve files from AWS S3—Andrew Welch does this neatly in his tutorial (one can skip the last step about Craft CMS, though)—I focus on the special configuration the Unity3D files need.

The new WebGL loader

The new WebGL loader requires that certain files are served in a specific way, contrary to the default web-server configurations.
From the forums:

When hosting such a build on a server, the following http headers should be added to the server responses in order to make the build load correctly:

  • .gz files should be served with a Content-Encoding: gzip response header.
  • .br files should be served with a Content-Encoding: br response header.
  • .wasm, .wasm.gz or .wasm.br files should be served with a Content-Type: application/wasm response header.
  • .js, .js.gz or .js.br files should be served with a Content-Type: application/javascript response header.

The Apache configuration example makes it even clearer:

<IfModule mod_mime.c>
# The following lines are required for builds without decompression fallback, compressed with gzip
RemoveType .gz
AddEncoding gzip .gz
AddType application/octet-stream .data.gz
AddType application/wasm .wasm.gz
AddType application/javascript .js.gz
AddType application/octet-stream .symbols.json.gz

# The following lines are required for builds without decompression fallback, compressed with brotli
RemoveType .br
RemoveLanguage .br
AddEncoding br .br
AddType application/octet-stream .data.br
AddType application/wasm .wasm.br
AddType application/javascript .js.br
AddType application/octet-stream .symbols.json.br

# The following line improves loading performance for uncompressed builds
AddType application/wasm .wasm
</IfModule>

On AWS

The easiest way to serve the Unity3D WebGL files via AWS CloudFront from an AWS S3 origin with the correct configuration is to set the correct Content-Type and Content-Encoding in the S3 bucket. Then CloudFront serves them to the user with the correct configuration directly.

To achieve this, one can set the correct metadata of the files via the AWS S3 management console: Select the file, open the “Actions” menu, select “Change metadata”, set the metadata in the opening pop-over on the right-hand side.

At one point I wrote a small helper script in Python, using boto3, to set the correct metadata after I uploaded the files manually: