Adding AR Quick Look Files to WordPress

A client tasked me with adding AR Quick Look files to their WordPress product portfolio site. We agreed on building this without a plugin, and this is what I’ve come up with:

Allow file uploads

We have to allow the upload of *.usdz and *.reality files to the WordPress media library. This is a pretty standard task, regardless of file type: Add the proper file extension and mime types via a filter, and check if the file type and file extension match on upload.

<?php

/**
 * Plugin Name: Upload AR Quick Look files
 * Description: Upload AR Quick Look files (usdz or reality) to your WordPress media library.
 * Author:      Alexander Goller
 * Author URI:  https://alexandergoller.com
 */

$arMimes = [
    'usdz'    => 'model/vnd.usdz+zip|application/octet-stream|model/x-vnd.usdz+zip',
    'reality' => 'model/vnd.reality|application/octet-stream|model/x-vnd.reality',
];

add_filter('wp_check_filetype_and_ext', function (array $data, string $file, string $filename, $mimes) use ($arMimes): array {
    if ( ! empty($data['ext']) && ! empty($data['type'])) {
        return $data;
    }
    $filetype = wp_check_filetype($filename, $mimes);
    if ( ! array_key_exists($filetype['ext'], $arMimes)) {
        return $data;
    }

    return [
        'ext'             => $filetype['ext'],
        'type'            => $filetype['type'],
        'proper_filename' => $data['proper_filename'],
    ];
}, 10, 4);

add_filter('upload_mimes', function (array $mimeTypes) use ($arMimes): array {
    if (array_key_exists('usdz', $mimeTypes)) {
        return $mimeTypes;
    }

    foreach ($arMimes as $ext => $mime) {
        $mimeTypes[$ext] = $mime;
    }

    return $mimeTypes;
});

You can download this as a small (mu-)plugin: https://gist.github.com/alpipego/50cd2e158ab52ce260aa758c4a626f0a

Add the proper markup

The object model file needs to be added in an anchor-element and a rel-attribute with the value of ar, while the first child element of this anchor MUST be an image tag:

<a href="https://example.com/wp-content/uploads/myobject.usdz" rel="ar" id="arql-link">
    <img …>
</a>

Browsers that support the rel="ar" (Safari 13+) will display this object in their AR Quick Look view, which lets you place objects in your home etc. Browsers that don’t support this will offer the download of the file for you, which is usually not the intended outcome. We can work around this by setting pointer-events to none on the #arql-link (and setting it to all on the child elements):

#arql-link {
    pointer-events: none;
}
#arql-link * {
    pointer-events: all;
}

And then detect via JS if the a tag supports rel="ar" and add the pointer-events back:

if (document.createElement('a').relList.supports('ar')) {
    document.getElementById('arql-link').style.pointerEvents = 'all';
}

Notes

This excellent article on Everything I Know About Launching iOS AR Quick Look From The Web mentions that you can have an empty <img /> tag as the child of the AR link. This did not work in my case (iOS 14.6 at the time of writing). I needed to add a src attribute (and depending on the image optional width and height).

If you need some example files to play around with, you can download some from Apple directly.

Your web server has to respond with the correct Content-Type, otherwise you can’t view the object in the AR view on iOS. On NGINX, you can add types like this:

types {
    model/vnd.usdz+zip usdz;
    model/vnd.reality reality;
}