Custom Domains on iCloud Email

I’ve been concerned for a while about Apple’s long-term commitment to iCloud email, and have been considering the painful task of switching my primary email address from my 10+ year old @me.com address[1]I managed a free MobileMe subscription back in the day. Remember paying for MobileMe‽ to one at my domain. That is not to say I think they’re actually going to shut down iCloud email, but their apparent lack of interest in the service is enough for me to wonder…

This past summer Apple announced we’ll soon be able to use custom domains with iCloud email. So as soon as I could (right in the middle of an important active email thread… do not recommend) I made the DNS changes to point my domain’s mail to iCloud. Now I can make the transition in email addresses slowly without needing to manage two inboxes. I feel better knowing that if they decide they don’t like email some day (like SD cards) I’d be a DNS change away from packing up my email address and moving it elsewhere.


Apple uses something I’ve not run into yet in the many email configurations I’ve come across; a redirect SPF record.

The switchover was painless, and the UI for the change was as pleasant as DNS can be. I would (subjectively) say it was the nicest onboarding experience for email I’ve been though.

References
1 I managed a free MobileMe subscription back in the day. Remember paying for MobileMe‽

Exclude posts from WordPress’s Sitemap

Starting with 5.5, WordPress now generates its own sitemap.xml without the need of a plugin. It’s possible to filter the results to exclude a specific post using the below filter:

function remove_page_from_sitemap ($args, $post_type ) {
    if ($post_type === "page") {
        $posts_not_in = [ 1234 ];
        
        if ( isset($args['post__not_in']) ) {
            $posts_not_in = array_merge( $posts_not_in, $args['post__not_in'] );
        }

        $args['post__not_in'] = $posts_not_in;
    }

    return $args;
}

add_filter( 'wp_sitemaps_posts_query_args', 'remove_page_from_sitemap', 10, 2);

That filter takes a familiar WP_Query argument, so it’s quite simple to add any additional filters, for example if you wanted to exclude posts from a specific term or from specific authors, using any existing WP_Query parameters.

Self-Hosting Fathom analytics behind Apache

I’m hosting Fathom on my domain at /fathom. It runs its own web server, so I’ve done this using a reverse proxy that makes the Fathom server accessible at that virtual directory. Their self-hosting instructions do have an example configuration for using Fathom with a reverse proxy through NGINX, but not Apache.

Fortunately the idea’s the same, so adapting it for Apache doesn’t involve too much. It does mean modifying the httpd.conf (or appropriate site-specific config file), and enabling a few additional Apache modules.

The Apache modules needed are mod_proxy, mod_proxy_http and mod_substitute. These can be enabled using a2enmod and restarting Apache:

sudo a2enmod proxy proxy_http substitute && sudo service apache2 restart

Now to enable the reverse proxy, I’ve added a new Location directive the VirtualHost in my site’s config file:

 <Location "/fathom">
        # Host and port of the Fathom instance
        ProxyPass http://127.0.0.1:8999

        # Updates redirect headers in responses from Fathom
        ProxyPassReverse http://127.0.0.1:8999

        # Send original Host header to Fathom
        ProxyPreserveHost On

        # Enables replacing of URLs in HTML elements
        ProxyHTMLEnable On

        # Load default mapping of attribute -> HTML elements that need replacing
        Include /etc/apache2/mods-available/proxy_html.conf

        # Define the regex in which to use to replace URLs in HTML
        ProxyHTMLURLMap ^(.*)$ /fathom/$1 [R]

        # Update the location of the /api/ calls in JavaScript responses from Fathom
        AddOutputFilterByType SUBSTITUTE application/javascript
        Substitute "s|/api/|/fathom/api/|niq"
</Location>

A little more on what each of those directives are doing:

  • ProxyPass http://127.0.0.1:8999
    Creates an entry point at the URL in the Location directive (the first line, in this case it’s /fathom), which in turn forwards those requests on to the Fathom server defined in this ProxyPass directive.
  • ProxyPassReverse http://127.0.0.1:8999
    Replaces redirects sent from Fathom (in the Location header) with the location that the client browser can access. In other words, when Fathom tries to redirect to an internal Login page (127.0.0.1:8999/login), this directive tells Apache to replace that with an externally-accessible URL (/fathom/login).
  • ProxyPreserveHost On
    Fathom’s example NGINX configuration explicitly passes on the Host header from the proxy to the upstream server (Fathom), so it’s safe to assume we should too.
  • ProxyHTMLEnable On
    Include /etc/apache2/mods-available/proxy_html.conf
    ProxyHTMLURLMap ^(.*)$ /fathom/$1 [R]

    These next few directives replace URLs in various HTML elements before sending them back to the browser. For example, <img> and <script> tags will need to be updated to point to the virtual directory (subfolder). Including the proxy_html.conf file imports a default mapping of attributes to elements so that Apache knows which attributes on which elements to update.
  • AddOutputFilterByType SUBSTITUTE application/javascript
    Substitute "s|/api/|/fathom/api/|niq"

    These final directives tell Apache to update URLs in JavaScript files. This is specifically needed for Fathom’s assets/js/scripts.js file, which makes multiple requests to files in the API folder. Just a note that Substitute uses a sed-like syntax for replacing text.