Provisional Authorization of User Notifications

Requesting provisional authorization to send local user notifications comes with some caveats but avoids interrupting the user with another permissions prompt.

https://useyourloaf.com/blog/provisional-authorization-of-user-notificatons

This is arguably a better user experience than requesting permission to send notifications the first time an app launches without any other context.

Cloudflare as a Free CDN for WordPress Assets

Why Use a CDN for Assets?

A Content Delivery Network (CDN) helps speed up a website by caching static assets (like JavaScript and CSS) on servers distributed around the world. This reduces latency and offloads traffic from the origin server, improving load times and user experience.

Cloudflare has a WordPress plugin that will help you cache everything, including dynamic content, on the Cloudflare edge. I didn’t want to do that, preferring more control over caching HTML content and less complexity around invalidating the Cloudflare cache. However, I still want to take advantage of Cloudflare’s CDN to cache my site’s static assets. I’ve found that you can still get great performance without proxying dynamic content through Cloudflare. (I do cache full HTML pages in Nginx.)

I’m already serving images from Cloudflare the imgproxy plugin I mentioned previously. It’s harder to target image URLs in WordPress posts, but you could use that plugin for inspiration.

Setting Up Cloudflare for WordPress Assets

Instead of placing my whole domain behind Cloudflare, I added a new subdomain dedicated to serving assets:

1. Add a new domain (or subdomain) to Cloudflare

  • In Cloudflare, I added cdn.example.com as a new site.
  • This domain is configured as a CNAME pointing to my WordPress site.

2. Enable Cloudflare caching

  • Since WordPress appends query strings for versioning (e.g., ?ver=6.4.2), new styles and scripts will always be available right after updating.

3. Ensure the subdomain serves assets correctly

  • If your web server allows wildcard domains, this should work without any additional configuration.
  • WordPress itself doesn’t care about the domain name for assets.

At this point, assets should be accessible via cdn.example.com, but WordPress is still serving them from the main domain. The next step is to rewrite asset URLs to use the CDN. I recommend testing that you can load static assets from Cloudflare before continuing. A good test is https://cdn.example.com/wp-includes/css/editor.min.css. That should load the expected stylesheet before switching asset URLs to your new CDN domain.

Rewriting WordPress Asset URLs

To make WordPress use the CDN, I created a small plugin to rewrite script and style URLs. This plugin ensures that any assets hosted on my WordPress site are served from cdn.example.com instead.

<?php

namespace CFCDN;

// Define your CDN URL
define( 'CDN_URL', 'https://cdn.example.com' );

/**
 * Replace the URL with CDN URL.
 *
 * @param string $url The original URL.
 * @return string The modified URL with CDN.
 */
function replace_url_with_cdn( $url ) {
    // Only modify the URL if it's a local URL
    $host = parse_url( $url, PHP_URL_HOST );
    $home_host = parse_url( home_url(), PHP_URL_HOST );
    if ( $host === $home_host ) {
        $parsed = parse_url( CDN_URL );
        $replace = $parsed['scheme'] . '://' . $parsed['host'];

        // Replace the site's URL with the CDN URL
        $url = str_replace( home_url(), $replace, $url );
    }

    return $url;
}

/**
 * Use the CDN URL everywhere we currently use a stylesheet URL
 *
 * For example, the favicon URL and preload URLs.
 * @param string stylesheet_dir_uri The source URL of the script.
 * @return string The modified script URL.
 */
function stylesheet_directory_uri( $stylesheet_dir_uri ) {
    return replace_url_with_cdn( $stylesheet_dir_uri );
}
add_filter( 'stylesheet_directory_uri', 'CFCDN\stylesheet_directory_uri' );

/**
 * Enqueue CDN URLs for scripts.
 *
 * @param string $src The source URL of the script.
 * @param string $handle The script's registered handle.
 * @return string The modified script URL.
 */
function enqueue_cdn_scripts( $src, $handle ) {
    return replace_url_with_cdn( $src );
}
add_filter( 'script_loader_src', 'CFCDN\enqueue_cdn_scripts', 10, 2 );

/**
 * Enqueue CDN URLs for styles.
 *
 * @param string $src The source URL of the style.
 * @param string $handle The style's registered handle.
 * @return string The modified style URL.
 */
function enqueue_cdn_styles( $src, $handle ) {
    return replace_url_with_cdn( $src );
}
add_filter( 'style_loader_src', 'CFCDN\enqueue_cdn_styles', 10, 2 );

This plugin works by:

  • Checking if the URL belongs to the WordPress site.
  • Rewriting it to use the CDN domain instead.
  • Applying this change to all scripts, styles, and even theme-related assets.

Once activated, WordPress automatically loads JavaScript and CSS from the Cloudflare CDN. It’s worth noting that this even serves scripts and styles from the CDN in wp-admin.

Final Thoughts

This approach lets me use Cloudflare’s caching for JavaScript and CSS assets without putting my entire site behind Cloudflare. The setup is straightforward:

  • Create a new Cloudflare domain as a CNAME to WordPress.
  • Enable caching for static assets.
  • Rewrite asset URLs using a small WordPress plugin.

With minimal effort, this improves page speed, reduces server load, and provides a better user experience. If you’re looking for a simple way to boost your WordPress site’s performance, this method is worth considering.

Simplicity First: Why Readable Code Is Better Code

When was the last time you opened a piece of code and thought, What is this even doing? Maybe you were debugging, adding a feature, or just trying to understand how it worked. Sometimes it’s your own code that trips you up. The problem isn’t that it’s broken—it’s that it’s hard to read.

Readable code matters more than we like to admit. It’s not just written once and forgotten; it’s read over and over again—by teammates, new hires, and sometimes by you, months or years later. In those moments, you will appreciate clear, simple code.

The temptation to future-proof everything is real. You imagine all the ways your code might need to change and try to prepare for them upfront. But here’s the thing: if you control the deployment pipeline, you don’t have to solve every problem now. Start simple. Simple code is easier to read, easier to understand, and, when the time comes, easier to adapt.

Why Readability Is the Most Important Metric

Developers spend far more time reading code than writing it. Whether you’re fixing a bug, adding a feature, or onboarding a new teammate, understanding the existing code is step one. If your code isn’t easy to read, it’s slowing everyone down.

Hard-to-read code creates friction. It makes debugging harder, onboarding slower, and feature development riskier. It also doesn’t age well. I’ve revisited code I wrote and found myself confused by my own decisions. If even the author can’t quickly understand the code, what chance does anyone else have?

Readable code isn’t a “nice-to-have.” It’s the foundation of maintainable software. The simpler and clearer your code is, the more effectively your team can work with it.

The Power of Simplicity

Readable code is simple code. It avoids unnecessary cleverness and prioritizes clarity over sophistication. A straightforward implementation may not win style points, but it will win over every developer who has to maintain it.

Consider this:

  • A clean, direct loop with meaningful variable names is immediately understandable.
  • A deeply nested chain of function calls might feel elegant when you write it, but it demands far more mental effort to parse later.

Simplicity is also a hedge against fragility. The fewer layers and abstractions your code has, the less likely it is to break or become difficult to debug. Clever code might feel satisfying to write, but simple code will serve your team better in the long run.

Avoiding the Trap of Unnecessary Abstractions

One of the most common mistakes developers make is over-engineering. You imagine all the ways your code might need to change someday and start adding abstractions to prepare. While the intention is good, the result is often needless complexity.

Abstractions aren’t bad by default. They can reduce duplication and encapsulate complexity when applied thoughtfully. But abstractions should solve real, present problems—not hypothetical ones. Over-abstraction creates layers of indirection that make your code harder to follow, not easier.

Before you add an abstraction, ask yourself:

  • Does this abstraction improve readability?
  • Does it solve a problem I have today?

If the answer to both isn’t a clear yes, skip it.

Controlling the Deployment Pipeline: Start Simple, Add Later

The beauty of writing programs you control is that you don’t need to solve every problem upfront. Libraries often have to support a wide range of use cases, requiring more extensibility and abstraction. But most programs are written to solve specific problems in specific contexts. They don’t need to work everywhere—they need to work here.

When you own the deployment pipeline, you have the luxury of starting simple. You don’t have to plan for every hypothetical scenario. If new needs arise, you can always refactor. It’s far easier to extend simple, readable code than to untangle an over-engineered solution.

For example, say you’re writing a program that interacts with a MySQL database. Instead of abstracting all database interactions just in case you switch to PostgreSQL later, write clear, direct queries. If you ever need to make a switch, your simple, readable code will make the transition easier—not harder.

Practical Strategies for Writing Simple, Readable Code

How do you write code that’s easy to read and maintain? Here are some principles to guide you:

  • Prioritize readability in code reviews. Reviews shouldn’t just focus on correctness—automated tests can handle that. Instead, ask, “Is this code simple and clear?”
  • Write for the reader. Use meaningful names, write concise functions, and favor straightforward logic. Assume the next person reading your code knows nothing about it.
  • Avoid unnecessary abstractions. Only abstract when it improves clarity or solves a real problem today.

Readable code isn’t just about writing for yourself. It’s about making life easier for your teammates, future hires, and, yes, future you.

Enforcing Simplicity in Code Reviews

Code reviews are one of the most important tools for maintaining a healthy codebase. But too often, reviews focus on whether the code works rather than whether it makes sense. While correctness is crucial, it’s something automated tools like tests, linters, and type checkers should already be doing. A big value add of code reviews lies in enforcing clear, simple code.

A good code review asks questions like:

  • Does this code make sense at first glance?
  • Is the logic straightforward, or does it require too much mental effort to follow?
  • Could this be written more simply?

By prioritizing these questions, reviews become less about nitpicking details and more about ensuring the code is approachable for everyone who will work with it in the future. Reviews are your chance to ask, “Will the next person who touches this code understand it quickly?” If the answer is no, then it’s worth revisiting.

Conclusion

Readable, simple code is the foundation of sustainable software development. It makes your codebase easier to fix, easier to extend, and easier to trust. And when you keep things simple, you give your team the flexibility to adapt as new needs arise.

So the next time you sit down to write code, ask yourself:

  • Is this easy to read?
  • Is this as simple as it could be?

If the answer is yes, you’re doing it right. Remember: it’s just code—it’s easy to change. Start simple, and let the future take care of itself.

Jeff Atwood, founder of Stack Overflow and Discourse:

The American Dream contains the path of hate, and the path of love. Throughout our history, one hand is always fighting the other. Which path are we choosing?

Our family pledges half our wealth toward an American Dream founded on love.

I didn’t know Warren Buffet was no longer giving his fortune to the Gates Foundation.

Last year he amended the pledge, giving all his wealth at death to a charitable trust run by his children, aged 71, 69, and 66, who do not make for natural charitable bedfellows.