[{"data":1,"prerenderedAt":783},["ShallowReactive",2],{"cms-blog-understanding-the-different-caching-layers-in-wordpress":3,"cms-blog":20},{"title":4,"excerpt":5,"slug":8,"rawDate":9,"date":10,"modified":11,"content":12,"readingTime":13,"acf":14,"tags":17,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Understanding the different caching layers in WordPress",{"raw":6,"plain":7},"\u003Cp>Caching is one of the easiest ways to improve the performance of a WordPress website, but it can also become unnecessarily complicated. You install a caching plugin, enable a few settings, and suddenly everything is supposed to be faster. The problem is that not all caches do the same thing. On the WordPress servers I&#8217;ve [&hellip;]\u003C\u002Fp>","Caching is one of the easiest ways to improve the performance of a WordPress website, but it can also become unnecessarily complicated. You install a caching plugin, enable a few settings, and suddenly everything is supposed to be faster. The problem is that not all caches do the same thing. On the WordPress servers I’ve […]","understanding-the-different-caching-layers-in-wordpress","2023-06-21T22:07:00",["Date","2023-06-21T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],"\u003Cp class=\"wp-block-paragraph\">Caching is one of the easiest ways to improve the performance of a WordPress website, but it can also become unnecessarily complicated.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">You install a caching plugin, enable a few settings, and suddenly everything is supposed to be faster.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The problem is that not all caches do the same thing.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">On the WordPress servers I’ve worked with, there are four main caching layers: the browser cache, Cloudflare CDN cache, Nginx proxy cache and Redis object cache.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Each one works at a different point in the request, and understanding what they do makes it much easier to work out where a performance problem is coming from.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Browser caching\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The first layer is the visitor’s browser.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">When somebody opens a website, the browser downloads resources such as CSS, JavaScript, fonts and images.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Most of those resources don’t need to be downloaded again every time somebody visits another page.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">HTTP caching headers tell the browser whether a response can be reused and for how long.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">For example:\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"torchlight\">\u003Ccode data-torchlight-id=\"8398aeae-9a5d-f337-99ae-57016af9b193\">\u003C!-- Syntax highlighted by torchlight.dev -->\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">1\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Cache-Control: public, max-age=31536000, immutable\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fcode>\n    \u003Cdiv class=\"copy-button__container js-copy-to-clipboard-container\">\n      \u003Cdiv class=\"copy-button__text js-copy-to-clipboard-notification\">Copied!\u003C\u002Fdiv>\n      \u003Cbutton type=\"button\" title=\"Copy to clipboard\" class=\"copy-button__button js-copy-to-clipboard-button\">\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n    \u003Cspan class=\"torchlight-copy-target js-copy-to-clipboard-target\" style=\"display: none\">Cache-Control: public, max-age=31536000, immutable\u003C\u002Fspan>\n    \u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">This tells the browser that the resource can be cached for a year and that it isn’t expected to change.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It’s particularly useful for assets with versioned or hashed filenames, where a new deployment produces a different URL.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">You wouldn’t generally want to apply that policy to ordinary HTML pages, because visitors could end up seeing old content long after it’s been updated.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Cloudflare CDN caching\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The next layer is Cloudflare.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Cloudflare sits between the visitor and the origin server, and can cache eligible responses at its edge locations.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">If an image is already cached at the edge, Cloudflare can return it without requesting it from the WordPress server again.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">That reduces the number of requests reaching the server and can improve performance for visitors who are geographically distant from it.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">By default, Cloudflare generally caches eligible static assets rather than all HTML pages.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">You can configure it to cache HTML too, but that needs more care.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">WordPress pages can contain user-specific content, especially for logged-in users, shopping baskets and checkout pages.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Caching the wrong HTML response and serving it to somebody else would be considerably worse than having a slightly slow website.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">For that reason, cache rules and bypass conditions matter just as much as the cache itself.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Nginx proxy caching\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The third layer is Nginx, running on the origin server.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">With EasyEngine, Nginx can cache generated page responses so subsequent requests don’t need to run WordPress again.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">For example, imagine a visitor requests an uncached blog post.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Nginx forwards the request to PHP, WordPress runs, queries the database and generates the HTML.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Nginx can then store that response.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">The next visitor requesting the same page may receive the cached HTML directly from Nginx, without PHP needing to do anything.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">This is particularly useful for pages that receive a lot of traffic but don’t change frequently.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It also reduces the amount of work PHP-FPM has to do, leaving more capacity for requests that can’t be cached.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Redis object caching\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Redis works differently from the other three layers.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Rather than caching the final HTML response, Redis stores objects that WordPress uses while generating the page.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">By default, WordPress has an object cache which only lasts for the duration of a request.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">With a persistent object cache backed by Redis, cached data can survive between requests.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">This avoids repeatedly fetching the same information from the database.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">For example, WordPress might need to retrieve site options, post metadata or other frequently accessed information.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">If that data is already available in Redis, WordPress can use it without repeating the database query.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Redis is particularly useful when the request cannot be served from a full-page cache, such as when a user is logged in or the page contains dynamic content.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">I’ve written a separate guide on \u003Ca href=\"\u002Fblog\u002Fsetting-up-redis-object-caching-in-wordpress\u002F\">setting up Redis object caching in WordPress\u003C\u002Fa>, including how to configure it with EasyEngine and verify that WordPress is actually using the cache.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">What happens when somebody visits a page?\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">With all four layers enabled, a request might look something like this:\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"torchlight\">\u003Ccode data-torchlight-id=\"c4625264-bd19-5a6b-292a-19aa1ea1396c\">\u003C!-- Syntax highlighted by torchlight.dev -->\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 1\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Visitor\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 2\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   |\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 3\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   v\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 4\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Browser cache\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 5\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   |\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 6\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   | Cache miss\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 7\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   v\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 8\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Cloudflare CDN\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\"> 9\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   |\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">10\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   | Cache miss\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">11\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   v\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">12\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Nginx proxy cache\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">13\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   |\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">14\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   | Cache miss\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">15\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   v\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">16\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">PHP \u002F WordPress\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">17\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   |\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">18\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   v\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">19\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Redis object cache\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">20\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   |\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">21\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   | Object cache miss\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">22\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">   v\u003C\u002Fspan>\u003C\u002Fdiv>\u003Cdiv class=\"line\">\u003Cspan style=\"color:#858585; text-align: right; -webkit-user-select: none; user-select: none;\" class=\"line-number\">23\u003C\u002Fspan>\u003Cspan style=\"color: #D4D4D4;\">Database\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fcode>\n    \u003Cdiv class=\"copy-button__container js-copy-to-clipboard-container\">\n      \u003Cdiv class=\"copy-button__text js-copy-to-clipboard-notification\">Copied!\u003C\u002Fdiv>\n      \u003Cbutton type=\"button\" title=\"Copy to clipboard\" class=\"copy-button__button js-copy-to-clipboard-button\">\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n    \u003Cspan class=\"torchlight-copy-target js-copy-to-clipboard-target\" style=\"display: none\">Visitor\n   |\n   v\nBrowser cache\n   |\n   | Cache miss\n   v\nCloudflare CDN\n   |\n   | Cache miss\n   v\nNginx proxy cache\n   |\n   | Cache miss\n   v\nPHP \u002F WordPress\n   |\n   v\nRedis object cache\n   |\n   | Object cache miss\n   v\nDatabase\u003C\u002Fspan>\n    \u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Not every request travels all the way through the stack.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A cached image might never reach Cloudflare, because the browser already has it.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A cached HTML page might be returned by Cloudflare or Nginx, without WordPress executing.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Redis only becomes relevant once PHP is actually running WordPress and needs to retrieve cached data.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">This is why adding Redis to a website with an already effective full-page cache might not produce a dramatic improvement in public page load times.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">The difficult part is clearing the cache\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Having several caching layers is useful until you update something and the changes don’t appear.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">You might clear the WordPress object cache, but Nginx is still serving an old HTML page.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">You clear Nginx, but Cloudflare has its own cached copy.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">And even after purging Cloudflare, the visitor’s browser might still be using a previously cached resource.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">This is why cache invalidation needs to be considered when configuring the stack.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">I try to make sure that publishing or updating content clears the appropriate page caches automatically, rather than relying on manually purging everything.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">For static assets, versioned filenames make this much easier because the URL changes whenever the file changes.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">I’d also avoid setting long cache lifetimes without having a way to invalidate them.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">More caching isn’t necessarily better\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">It’s tempting to enable every caching option available, but each additional layer introduces another place where something can go wrong.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A badly configured cache can serve stale content, interfere with dynamic pages or make debugging considerably harder.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">There’s also a difference between reducing server load and improving the experience of the visitor.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">If Cloudflare is already returning a page from the edge, speeding up the WordPress database won’t make that particular response much faster.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">I find it more useful to understand where requests are spending their time and optimise the layer that’s actually doing the work.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Browser caching reduces repeated downloads. Cloudflare reduces requests to the origin. Nginx reduces PHP execution. Redis reduces repeated database work within WordPress.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">They complement each other, but they aren’t interchangeable.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Once you understand that distinction, WordPress caching becomes a lot less mysterious.\u003C\u002Fp>",6,{"project_url":15,"github":15,"icons":16},"",[],[],"Joe",null,[21,136,246,364,487,591,698],[22,34,46,58,70,81,92,103,115,126],{"title":23,"excerpt":24,"slug":27,"date":28,"modified":29,"readingTime":30,"acf":31,"tags":33,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How AI helped me add my Mitsubishi Delica D:5 to UK insurance databases",{"raw":25,"plain":26},"\u003Cp>Earlier this year I bought a 2007 Mitsubishi Delica D:5. The D:5 has been sold in Japan since 2007 but was never officially sold in the UK. Mine is a Japanese import, which means that while it is perfectly legal and registered with the DVLA, getting insurance for it can be a little more complicated [&hellip;]\u003C\u002Fp>","Earlier this year I bought a 2007 Mitsubishi Delica D:5. The D:5 has been sold in Japan since 2007 but was never officially sold in the UK. Mine is a Japanese import, which means that while it is perfectly legal and registered with the DVLA, getting insurance for it can be a little more complicated […]","how-ai-helped-me-add-my-mitsubishi-delica-d5-to-uk-insurance-databases",["Date","2026-11-06T00:00:00.000Z"],["Date","2026-11-06T00:00:00.000Z"],8,{"project_url":15,"github":15,"icons":32},[],[],{"title":35,"excerpt":36,"slug":39,"date":40,"modified":41,"readingTime":42,"acf":43,"tags":45,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Moving my site from Netlify to Cloudflare Workers",{"raw":37,"plain":38},"\u003Cp>I moved this site&#8217;s builds, hosting, forms and images from Netlify to Cloudflare Workers, and upgraded it to Nuxt 4 and TypeScript along the way. Here&#8217;s what moved where, and what caught me out.\u003C\u002Fp>","I moved this site’s builds, hosting, forms and images from Netlify to Cloudflare Workers, and upgraded it to Nuxt 4 and TypeScript along the way. Here’s what moved where, and what caught me out.","moving-from-netlify-to-cloudflare-workers",["Date","2026-10-27T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],2,{"project_url":15,"github":15,"icons":44},[],[],{"title":47,"excerpt":48,"slug":51,"date":52,"modified":53,"readingTime":54,"acf":55,"tags":57,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Replacing a BI tool that couldn’t handle 40 million rows",{"raw":49,"plain":50},"\u003Cp>Our reporting went from stale database syncs, to MySQL views, to a BI tool that copied everything and choked on our biggest table. Querying the database directly with Grafana cut dashboard updates from two hours to near-instant.\u003C\u002Fp>","Our reporting went from stale database syncs, to MySQL views, to a BI tool that copied everything and choked on our biggest table. Querying the database directly with Grafana cut dashboard updates from two hours to near-instant.","replacing-gogrow-with-grafana",["Date","2026-09-29T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],3,{"project_url":15,"github":15,"icons":56},[],[],{"title":59,"excerpt":60,"slug":63,"date":64,"modified":65,"readingTime":66,"acf":67,"tags":69,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Scaling ECS on PHP-FPM workers instead of CPU and memory",{"raw":61,"plain":62},"\u003Cp>Our ECS services scaled on CPU and memory, which meant traffic spikes took the platform down before a new container ever started. Scaling on busy PHP-FPM workers fixed the outages and let us run 3 containers instead of 8.\u003C\u002Fp>","Our ECS services scaled on CPU and memory, which meant traffic spikes took the platform down before a new container ever started. Scaling on busy PHP-FPM workers fixed the outages and let us run 3 containers instead of 8.","scaling-ecs-on-php-fpm-workers",["Date","2026-09-15T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],9,{"project_url":15,"github":15,"icons":68},[],[],{"title":71,"excerpt":72,"slug":75,"date":76,"modified":77,"readingTime":30,"acf":78,"tags":80,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Running our PHPUnit suite on one EC2 runner instead of 40 GitHub runners",{"raw":73,"plain":74},"\u003Cp>Our PHPUnit suite was split across a 40-job matrix of GitHub-hosted runners. Moving it onto a single self-hosted EC2 runner simplified the pipeline and saves us over $200 a month.\u003C\u002Fp>","Our PHPUnit suite was split across a 40-job matrix of GitHub-hosted runners. Moving it onto a single self-hosted EC2 runner simplified the pipeline and saves us over $200 a month.","phpunit-on-a-self-hosted-ec2-runner",["Date","2026-09-01T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":79},[],[],{"title":82,"excerpt":83,"slug":86,"date":87,"modified":88,"readingTime":89,"acf":90,"tags":91,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How to download a Google Sheet on a cron",{"raw":84,"plain":85},"\u003Cp>Working with Google Cloud can be confusing for beginners and sometimes all you need is to manipulate a Google Sheet. I have a couple of use cases for downloading a sheet and uploading a sheet. I haven&#8217;t quite figured out the upload part yet, but I have got downloading to work. I&#8217;ve decided to write [&hellip;]\u003C\u002Fp>","Working with Google Cloud can be confusing for beginners and sometimes all you need is to manipulate a Google Sheet. I have a couple of use cases for downloading a sheet and uploading a sheet. I haven’t quite figured out the upload part yet, but I have got downloading to work. I’ve decided to write […]","how-to-download-a-google-sheet-on-a-cron",["Date","2024-02-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],4,{"project_url":15,"github":15,"icons":15},[],{"title":93,"excerpt":94,"slug":97,"date":98,"modified":99,"readingTime":100,"acf":101,"tags":102,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How to add Custom Variables to LiveChat",{"raw":95,"plain":96},"\u003Cp>I had a task to add a Google Analytics ID to the user profile in LiveChat. We wanted to be able to match up the person we were chatting to with the analytics data in Google. This looked really simple according to their docs. You can just use the following function: What their docs failed [&hellip;]\u003C\u002Fp>","I had a task to add a Google Analytics ID to the user profile in LiveChat. We wanted to be able to match up the person we were chatting to with the analytics data in Google. This looked really simple according to their docs. You can just use the following function: What their docs failed […]","how-to-add-custom-variables-to-livechat",["Date","2024-01-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],1,{"project_url":15,"github":15,"icons":15},[],{"title":104,"excerpt":105,"slug":108,"date":109,"modified":110,"readingTime":111,"acf":112,"tags":114,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Moving Gatsby Image Processing to Netlify Image CDN",{"raw":106,"plain":107},"\u003Cp>With Netlify&#8217;s acquisition of Gatsby and subsequent shutdown of Gatsby Cloud, it left many users racing to migrate their deployment pipeline to Netlify. Netlify did do well to implement some of Gatsby Cloud&#8217;s features, but the overall experience feels half-baked. Many of the docs are incomplete, or haven&#8217;t been updated in a couple of years. [&hellip;]\u003C\u002Fp>","With Netlify’s acquisition of Gatsby and subsequent shutdown of Gatsby Cloud, it left many users racing to migrate their deployment pipeline to Netlify. Netlify did do well to implement some of Gatsby Cloud’s features, but the overall experience feels half-baked. Many of the docs are incomplete, or haven’t been updated in a couple of years. […]","moving-gatsby-image-processing-to-netlify-image-cdn",["Date","2023-12-19T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],7,{"project_url":15,"github":15,"icons":113},[],[],{"title":116,"excerpt":117,"slug":120,"date":121,"modified":122,"readingTime":89,"acf":123,"tags":125,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Creating a reusable date component for Nuxt",{"raw":118,"plain":119},"\u003Cp>When I was building my personal website with Nuxt, I wanted something a bit more interesting than a plain text date next to each blog post. I ended up creating a small date component which displays the day in a coloured block, with the month and year underneath in a ribbon shape. It&#8217;s a fairly [&hellip;]\u003C\u002Fp>","When I was building my personal website with Nuxt, I wanted something a bit more interesting than a plain text date next to each blog post. I ended up creating a small date component which displays the day in a coloured block, with the month and year underneath in a ribbon shape. It’s a fairly […]","creating-a-reusable-date-component-for-nuxt",["Date","2023-11-20T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],{"project_url":15,"github":15,"icons":124},[],[],{"title":127,"excerpt":128,"slug":131,"date":132,"modified":133,"readingTime":42,"acf":134,"tags":135,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"This one Nuxt trick prevents broken deploys",{"raw":129,"plain":130},"\u003Cp>Have you ever experienced broken deploys while using Nuxt? It can be frustrating when your build encounters errors, but still proceeds to deploy all the files, resulting in broken pages on your website. Fortunately, I discovered a handy Nuxt trick that prevents such broken deploys and ensures a more reliable deployment process. In my case, [&hellip;]\u003C\u002Fp>","Have you ever experienced broken deploys while using Nuxt? It can be frustrating when your build encounters errors, but still proceeds to deploy all the files, resulting in broken pages on your website. Fortunately, I discovered a handy Nuxt trick that prevents such broken deploys and ensures a more reliable deployment process. In my case, […]","this-one-nuxt-trick-prevents-broken-deploys",["Date","2023-07-12T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],[137,144,155,165,177,189,202,213,223,235],{"title":4,"excerpt":138,"slug":8,"date":139,"modified":140,"readingTime":13,"acf":141,"tags":143,"author":18,"featuredMediaUrl":19,"featuredMedia":19},{"raw":6,"plain":7},["Date","2023-06-21T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":142},[],[],{"title":145,"excerpt":146,"slug":149,"date":150,"modified":151,"readingTime":89,"acf":152,"tags":154,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Managing Docker logs with logrotate",{"raw":147,"plain":148},"\u003Cp>One of the less interesting parts of running your own server is dealing with logs. They&#8217;re useful when something goes wrong, but most of the time you don&#8217;t need to keep months of access logs, error logs and application output. If they&#8217;re left alone, they can gradually consume a surprising amount of disk space. I [&hellip;]\u003C\u002Fp>","One of the less interesting parts of running your own server is dealing with logs. They’re useful when something goes wrong, but most of the time you don’t need to keep months of access logs, error logs and application output. If they’re left alone, they can gradually consume a surprising amount of disk space. I […]","managing-docker-logs-with-logrotate",["Date","2023-06-20T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":153},[],[],{"title":156,"excerpt":157,"slug":160,"date":161,"modified":162,"readingTime":54,"acf":163,"tags":164,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"The importance of read time for blog posts and how to automatically generate it using Node.js",{"raw":158,"plain":159},"\u003Cp>In today&#8217;s fast-paced digital world, attention spans are getting shorter, and users often have limited time to consume content. As a result, providing readers with an estimated reading time can be a valuable feature for any blog or content-based website. Why having a read time for a blog post is important Automatically generate a read [&hellip;]\u003C\u002Fp>","In today’s fast-paced digital world, attention spans are getting shorter, and users often have limited time to consume content. As a result, providing readers with an estimated reading time can be a valuable feature for any blog or content-based website. Why having a read time for a blog post is important Automatically generate a read […]","the-importance-of-read-time-for-blog-posts-and-how-to-automatically-generate-it-using-node-js",["Date","2023-06-20T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":166,"excerpt":167,"slug":170,"date":171,"modified":172,"readingTime":30,"acf":173,"tags":174,"author":18,"featuredMediaUrl":175,"featuredMedia":176},"Adding syntax highlighting to my blog with Torchlight",{"raw":168,"plain":169},"\u003Cp>Background A little while ago I read the following blog post, Web Component for a Code Block by Chris Coyier, it got me thinking about how I could enhance the code blocks on my website. This is a tech blog after all, and from time to time I want to share tips and tricks which involve [&hellip;]\u003C\u002Fp>","Background A little while ago I read the following blog post, Web Component for a Code Block by Chris Coyier, it got me thinking about how I could enhance the code blocks on my website. This is a tech blog after all, and from time to time I want to share tips and tricks which involve […]","adding-syntax-highlighting-to-my-blog-with-torchlight",["Date","2023-06-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe1e861af4f6259527d0fc8ad9790f0070bbbbc9e3026b722390c4894a9472d28\u002Fe1e861af4f625952-NVIDIA-GeForce-Overlay-DT-2023-06-16-14.07.00-1.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe1e861af4f6259527d0fc8ad9790f0070bbbbc9e3026b722390c4894a9472d28\u002Fe1e861af4f625952-NVIDIA-GeForce-Overlay-DT-2023-06-16-14.07.00-1.png",{"title":178,"excerpt":179,"slug":182,"date":183,"modified":184,"readingTime":89,"acf":185,"tags":186,"author":18,"featuredMediaUrl":187,"featuredMedia":188},"Adding Algolia search to my 404 page",{"raw":180,"plain":181},"\u003Cp>My site is pretty small, so I don&#8217;t really need search functionality, but the Netlify Algolia plugin looked easy enough to use and a bit of fun. Diving into the docs, I got a bit overwhelmed. Algolia&#8217;s breadth of capabilities is huge. They definitely seem like the go-to for fully customisable search on a Jamstack [&hellip;]\u003C\u002Fp>","My site is pretty small, so I don’t really need search functionality, but the Netlify Algolia plugin looked easy enough to use and a bit of fun. Diving into the docs, I got a bit overwhelmed. Algolia’s breadth of capabilities is huge. They definitely seem like the go-to for fully customisable search on a Jamstack […]","adding-algolia-search-to-my-404-page",["Date","2023-06-13T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F109426a35d77479e1e989a82f03158349304fd98349223e9939110f26ef80377\u002F109426a35d77479e-NVIDIA-GeForce-Overlay-DT-2023-06-13-21.09.10.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F109426a35d77479e1e989a82f03158349304fd98349223e9939110f26ef80377\u002F109426a35d77479e-NVIDIA-GeForce-Overlay-DT-2023-06-13-21.09.10.png",{"title":190,"excerpt":191,"slug":194,"date":195,"modified":196,"readingTime":89,"acf":197,"tags":201,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Notification of a delivery failure in Mailgun",{"raw":192,"plain":193},"\u003Cp>When you use an email service provider like Gmail, you get delivery failure emails. These emails are great because it enables you to reach out to your intended recipient in another way, or just retry the email later on. Because I use Mailgun with Gmail&#8217;s Send Mail As feature for my custom domains, I needed [&hellip;]\u003C\u002Fp>","When you use an email service provider like Gmail, you get delivery failure emails. These emails are great because it enables you to reach out to your intended recipient in another way, or just retry the email later on. Because I use Mailgun with Gmail’s Send Mail As feature for my custom domains, I needed […]","notification-of-a-delivery-failure-in-mailgun",["Date","2023-05-31T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],{"project_url":15,"github":198,"icons":199},"https:\u002F\u002Fgithub.com\u002FGalexia-Agency\u002Fmailgun-failed-webhook",[200],"Custom",[],{"title":203,"excerpt":204,"slug":207,"date":208,"modified":209,"readingTime":54,"acf":210,"tags":212,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Setting up Redis object caching in WordPress",{"raw":205,"plain":206},"\u003Cp>WordPress makes a lot of database queries. Even a fairly simple page can involve dozens of queries to fetch settings, posts, metadata and other information. WordPress has a built-in object cache which avoids repeating queries within the same request. The problem is that, by default, the cache disappears as soon as the request finishes. The [&hellip;]\u003C\u002Fp>","WordPress makes a lot of database queries. Even a fairly simple page can involve dozens of queries to fetch settings, posts, metadata and other information. WordPress has a built-in object cache which avoids repeating queries within the same request. The problem is that, by default, the cache disappears as soon as the request finishes. The […]","setting-up-redis-object-caching-in-wordpress",["Date","2023-05-17T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":211},[],[],{"title":214,"excerpt":215,"slug":218,"date":219,"modified":220,"readingTime":100,"acf":221,"tags":222,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Dragging to Scroll with JavaScript",{"raw":216,"plain":217},"\u003Cp>My portfolio has some cards to showcase projects and blog posts. On mobile, these cards display in a horizontal slider, which is easy enough to scroll on a touchscreen, or trackpad, but what if someone is viewing the website at a small size on a device with a mouse? Well they can of course use [&hellip;]\u003C\u002Fp>","My portfolio has some cards to showcase projects and blog posts. On mobile, these cards display in a horizontal slider, which is easy enough to scroll on a touchscreen, or trackpad, but what if someone is viewing the website at a small size on a device with a mouse? Well they can of course use […]","dragging-to-scroll-with-javascript",["Date","2023-03-30T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":224,"excerpt":225,"slug":228,"date":229,"modified":230,"readingTime":231,"acf":232,"tags":234,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Using Google Sheets as a database for a Vue application",{"raw":226,"plain":227},"\u003Cp>I had a client who needed to display a list of churches taking part in an event. The list needed to be organised by area, include information about each church, and allow visitors to download a PDF they could print off. The information was already being managed in Google Sheets, so rather than move everything [&hellip;]\u003C\u002Fp>","I had a client who needed to display a list of churches taking part in an event. The list needed to be organised by area, include information about each church, and allow visitors to download a PDF they could print off. The information was already being managed in Google Sheets, so rather than move everything […]","using-google-sheets-as-a-database-for-a-vue-application",["Date","2022-11-08T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],5,{"project_url":15,"github":15,"icons":233},[],[],{"title":236,"excerpt":237,"slug":240,"date":241,"modified":242,"readingTime":89,"acf":243,"tags":245,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Replacing WP-Cron with a proper scheduler",{"raw":238,"plain":239},"\u003Cp>WordPress has a built-in task scheduling system called WP-Cron. It handles things like publishing scheduled posts, checking for updates and running background tasks created by plugins. The strange thing about WP-Cron is that, by default, it doesn&#8217;t run on a proper schedule. Instead, WordPress checks whether any tasks are due when somebody visits the website. [&hellip;]\u003C\u002Fp>","WordPress has a built-in task scheduling system called WP-Cron. It handles things like publishing scheduled posts, checking for updates and running background tasks created by plugins. The strange thing about WP-Cron is that, by default, it doesn’t run on a proper schedule. Instead, WordPress checks whether any tasks are due when somebody visits the website. […]","replacing-wp-cron-with-a-proper-scheduler",["Date","2022-10-21T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":244},[],[],[247,258,269,280,290,304,317,330,340,350],{"title":248,"excerpt":249,"slug":252,"date":253,"modified":254,"readingTime":89,"acf":255,"tags":257,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Backing up WordPress to Cloudflare R2",{"raw":250,"plain":251},"\u003Cp>I&#8217;ve been using Cloudflare R2 as somewhere to store WordPress backups. Keeping backups on the same server as the website isn&#8217;t particularly useful if that server suffers a serious failure. You might be able to recover from a bad plugin update, but you won&#8217;t have much luck if the entire server disappears. I wanted the [&hellip;]\u003C\u002Fp>","I’ve been using Cloudflare R2 as somewhere to store WordPress backups. Keeping backups on the same server as the website isn’t particularly useful if that server suffers a serious failure. You might be able to recover from a bad plugin update, but you won’t have much luck if the entire server disappears. I wanted the […]","backing-up-wordpress-to-cloudflare-r2",["Date","2022-05-22T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":256},[],[],{"title":259,"excerpt":260,"slug":263,"date":264,"modified":265,"readingTime":231,"acf":266,"tags":268,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Migrating WordPress between servers without unnecessary downtime",{"raw":261,"plain":262},"\u003Cp>Moving a WordPress website between servers is usually fairly straightforward. The difficult part is making sure everything works on the new server before directing visitors to it. I&#8217;ve migrated WordPress sites between hosting providers, and the approach I prefer is to get the entire website working on the new server before making any DNS changes. [&hellip;]\u003C\u002Fp>","Moving a WordPress website between servers is usually fairly straightforward. The difficult part is making sure everything works on the new server before directing visitors to it. I’ve migrated WordPress sites between hosting providers, and the approach I prefer is to get the entire website working on the new server before making any DNS changes. […]","migrating-wordpress-between-servers-without-unnecessary-downtime",["Date","2021-08-13T00:00:00.000Z"],["Date","2026-11-10T00:00:00.000Z"],{"project_url":15,"github":15,"icons":267},[],[],{"title":270,"excerpt":271,"slug":274,"date":275,"modified":276,"readingTime":89,"acf":277,"tags":279,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Scraping a website to migrate it to WordPress",{"raw":272,"plain":273},"\u003Cp>I was tasked with migrating an old website from Yahoo Pages to WordPress. Normally, migrating a website is fairly straightforward if you can export its content or access the database. Unfortunately, that wasn&#8217;t an option here. The website contained a collection of articles about local and world history. I needed to get that content out [&hellip;]\u003C\u002Fp>","I was tasked with migrating an old website from Yahoo Pages to WordPress. Normally, migrating a website is fairly straightforward if you can export its content or access the database. Unfortunately, that wasn’t an option here. The website contained a collection of articles about local and world history. I needed to get that content out […]","scraping-a-website-to-migrate-it-to-wordpress",["Date","2021-03-08T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],{"project_url":15,"github":15,"icons":278},[],[],{"title":281,"excerpt":282,"slug":285,"date":286,"modified":287,"readingTime":42,"acf":288,"tags":289,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"How To Secure your server using UFW and Cloudflare",{"raw":283,"plain":284},"\u003Cp>This guide will help you use UFW (uncomplicated firewall) to block all traffic to your server other than traffic coming via Cloudflare, or for essential operations such as FTP and SSH. Why would you want to do this? Cloudflare will protect your site from all manner of attacks. However, your server may still be vulnerable. [&hellip;]\u003C\u002Fp>","This guide will help you use UFW (uncomplicated firewall) to block all traffic to your server other than traffic coming via Cloudflare, or for essential operations such as FTP and SSH. Why would you want to do this? Cloudflare will protect your site from all manner of attacks. However, your server may still be vulnerable. […]","how-to-secure-your-server-using-ufw-and-cloudflare",["Date","2021-01-11T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":291,"excerpt":292,"slug":295,"date":296,"modified":297,"readingTime":100,"acf":298,"tags":303,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Adobe XD Challenge Calculator",{"raw":293,"plain":294},"\u003Cp>The third challenge was to create a calculator. I wanted to practise my CSS art and so chose an image of an old Casio calculator and tried to recreate it as closely as possible. It was quite a challenge creating the code for the calculator to function. It wasn&#8217;t as simple as just adding numbers [&hellip;]\u003C\u002Fp>","The third challenge was to create a calculator. I wanted to practise my CSS art and so chose an image of an old Casio calculator and tried to recreate it as closely as possible. It was quite a challenge creating the code for the calculator to function. It wasn’t as simple as just adding numbers […]","adobe-xd-challenge-calculator",["Date","2020-08-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":299,"github":300,"icons":301},"https:\u002F\u002Fvue-calculator-joe.netlify.app","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FVue-Calculator",[302],"Vue",[],{"title":305,"excerpt":306,"slug":309,"date":310,"modified":311,"readingTime":100,"acf":312,"tags":316,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Adobe XD Challenge Fitness App",{"raw":307,"plain":308},"\u003Cp>The second challenge was to create a fitness app. I chose to make an activity tracker. I took inspiration from Lifelog, an app by Sony that I used for many years. I used the Google Maps API and created a component in Vue for the activities.\u003C\u002Fp>","The second challenge was to create a fitness app. I chose to make an activity tracker. I took inspiration from Lifelog, an app by Sony that I used for many years. I used the Google Maps API and created a component in Vue for the activities.","adobe-xd-challenge-fitness-app",["Date","2020-08-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":313,"github":314,"icons":315},"https:\u002F\u002Fjoe-exercise.netlify.app","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FExercise-App",[302],[],{"title":318,"excerpt":319,"slug":322,"date":323,"modified":324,"readingTime":100,"acf":325,"tags":329,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Adobe XD Challenge – Music Player",{"raw":320,"plain":321},"\u003Cp>Me and Eleanor Morgan participated in the Adobe XD Challenge. I wanted to use Vue.js rather than practise my skills in XD as I view myself as more of a developer than a designer. The first challenge was to create a music player. I played around with the audio API and used some CSS animations.\u003C\u002Fp>","Me and Eleanor Morgan participated in the Adobe XD Challenge. I wanted to use Vue.js rather than practise my skills in XD as I view myself as more of a developer than a designer. The first challenge was to create a music player. I played around with the audio API and used some CSS animations.","adobe-xd-challenge-music-player",["Date","2020-08-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":326,"github":327,"icons":328},"http:\u002F\u002Fmusic-player.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002Fmusic-player",[302],[],{"title":331,"excerpt":332,"slug":335,"date":336,"modified":337,"readingTime":54,"acf":338,"tags":339,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"React and Vue re-visited",{"raw":333,"plain":334},"\u003Cp>After re-creating my portfolio with Gatsby (which uses React) and building an app for a client in Vue I feel I have more knowledge about the two JavaScript frameworks to give an informed opinion on both. When I was first starting out using these sort of frameworks I wrote this article on my thoughts. I [&hellip;]\u003C\u002Fp>","After re-creating my portfolio with Gatsby (which uses React) and building an app for a client in Vue I feel I have more knowledge about the two JavaScript frameworks to give an informed opinion on both. When I was first starting out using these sort of frameworks I wrote this article on my thoughts. I […]","react-and-vue-re-visited",["Date","2020-05-09T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":341,"excerpt":342,"slug":345,"date":346,"modified":347,"readingTime":42,"acf":348,"tags":349,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"What is a Front-End Developer?",{"raw":343,"plain":344},"\u003Cp>I&#8217;ve been asking myself this question a lot recently after applying for quite a few web development placements. The experience has been enlightening, teaching me a great deal about the industry. I&#8217;ve been reflecting on what I&#8217;m good at in web development and what I enjoy. Whilst freelancing I&#8217;d describe myself as a Full-Stack Developer. [&hellip;]\u003C\u002Fp>","I’ve been asking myself this question a lot recently after applying for quite a few web development placements. The experience has been enlightening, teaching me a great deal about the industry. I’ve been reflecting on what I’m good at in web development and what I enjoy. Whilst freelancing I’d describe myself as a Full-Stack Developer. […]","what-is-a-front-end-developer",["Date","2020-05-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":351,"excerpt":352,"slug":355,"date":356,"modified":357,"readingTime":100,"acf":358,"tags":363,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Points Of Interest",{"raw":353,"plain":354},"\u003Cp>Following on from developing the HitTastic! site we had to create a site in PHP that allows users to view POI&#8217;s stored in a database, and contribute to this database. We had to do some basic styles to go along with it.\u003C\u002Fp>","Following on from developing the HitTastic! site we had to create a site in PHP that allows users to view POI’s stored in a database, and contribute to this database. We had to do some basic styles to go along with it.","points-of-interest",["Date","2020-04-28T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":359,"github":360,"icons":361},"https:\u002F\u002Fpoi.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FPointsOfInterest-MySQLi",[362],"PHP",[],[365,377,390,400,414,428,441,454,464,477],{"title":366,"excerpt":367,"slug":370,"date":371,"modified":372,"readingTime":100,"acf":373,"tags":376,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"HitTastic!",{"raw":368,"plain":369},"\u003Cp>In my second year of university, I did a PHP unit where we were tasked with creating a site showing the number one songs from a certain year. We had to make a login, connect to a database, and perform a search.\u003C\u002Fp>","In my second year of university, I did a PHP unit where we were tasked with creating a site showing the number one songs from a certain year. We had to make a login, connect to a database, and perform a search.","hittastic",["Date","2020-04-28T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":374,"icons":375},"https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FPHP-Lessons",[362],[],{"title":378,"excerpt":379,"slug":382,"date":383,"modified":384,"readingTime":100,"acf":385,"tags":389,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Hangman",{"raw":380,"plain":381},"\u003Cp>Whilst I was searching for a placement I had a few tasks to complete for various roles I was interviewing for. One of these tasks was to create a simple Hangman game in PHP.\u003C\u002Fp>","Whilst I was searching for a placement I had a few tasks to complete for various roles I was interviewing for. One of these tasks was to create a simple Hangman game in PHP.","hangman",["Date","2020-04-28T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":386,"github":387,"icons":388},"https:\u002F\u002Fhangman.joebailey.xyz\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FHangman",[362],[],{"title":391,"excerpt":392,"slug":395,"date":396,"modified":397,"readingTime":42,"acf":398,"tags":399,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Re-creating my portfolio with Gatsby",{"raw":393,"plain":394},"\u003Cp>You may have read Re-creating my portfolio with React where I talked about my experiences converting my simple static portfolio into a React website, turning reusable objects on the page into React components. This inspired me to learn Gatsby, a static site generator that uses React. I was previously using my a category on my [&hellip;]\u003C\u002Fp>","You may have read Re-creating my portfolio with React where I talked about my experiences converting my simple static portfolio into a React website, turning reusable objects on the page into React components. This inspired me to learn Gatsby, a static site generator that uses React. I was previously using my a category on my […]","re-creating-my-portfolio-with-gatsby",["Date","2020-04-27T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":401,"excerpt":402,"slug":405,"date":406,"modified":407,"readingTime":100,"acf":408,"tags":413,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Firebase Chat App",{"raw":403,"plain":404},"\u003Cp>In my first year of University I had a go at creating a chat app using Firebase following my lecturers instructions. I was the only person in my class to succeed. Go ahead, type something.\u003C\u002Fp>","In my first year of University I had a go at creating a chat app using Firebase following my lecturers instructions. I was the only person in my class to succeed. Go ahead, type something.","firebase-chat-app",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":409,"github":410,"icons":411},"https:\u002F\u002Fchat-app-a7f51.firebaseapp.com\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002Ffirebase_chat_app",[412],"Firebase",[],{"title":415,"excerpt":416,"slug":419,"date":420,"modified":421,"readingTime":100,"acf":422,"tags":427,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"React Tic Tac Toe",{"raw":417,"plain":418},"\u003Cp>My first venture into the world of React was building this Tic Tac Toe game using the React Docs. It also helped me get to grips with CodePen for creating small little projects.\u003C\u002Fp>","My first venture into the world of React was building this Tic Tac Toe game using the React Docs. It also helped me get to grips with CodePen for creating small little projects.","react-tic-tac-toe",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":423,"github":424,"icons":425},"https:\u002F\u002Fcodepen.io\u002Fjoebailey26\u002Fpen\u002FpoogwjN","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FReact-Tic-Tac-Toe",[426],"React",[],{"title":429,"excerpt":430,"slug":433,"date":434,"modified":435,"readingTime":100,"acf":436,"tags":440,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Vue To-Do List",{"raw":431,"plain":432},"\u003Cp>After experimenting using Vue in my Photography Website I decided to have a go at making a To-Do List. You can create and delete To Dos but they don&#8217;t currently persist. This is something I wish to add in the future.\u003C\u002Fp>","After experimenting using Vue in my Photography Website I decided to have a go at making a To-Do List. You can create and delete To Dos but they don’t currently persist. This is something I wish to add in the future.","vue-to-do-list",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":437,"github":438,"icons":439},"https:\u002F\u002Frelaxed-cori-9310e4.netlify.app\u002F","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FVue-To-Do-List",[302],[],{"title":442,"excerpt":443,"slug":446,"date":447,"modified":448,"readingTime":100,"acf":449,"tags":453,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"To-Do List",{"raw":444,"plain":445},"\u003Cp>As part of my university course we were tasked with creating a To Do List in Vanilla JavaScript. For many, it was also an introduction into using NPM and BrowserSync for the first time. We also experimented with using Local Browser Storage.\u003C\u002Fp>","As part of my university course we were tasked with creating a To Do List in Vanilla JavaScript. For many, it was also an introduction into using NPM and BrowserSync for the first time. We also experimented with using Local Browser Storage.","to-do-list",["Date","2020-04-24T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":450,"github":451,"icons":452},"https:\u002F\u002Fcodepen.io\u002Fjoebailey26\u002Fpen\u002FwvvbBpN","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FJavaScript-To-Do-List",[200],[],{"title":455,"excerpt":456,"slug":459,"date":460,"modified":461,"readingTime":100,"acf":462,"tags":463,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Re-creating my Portfolio with React",{"raw":457,"plain":458},"\u003Cp>I&#8217;ve just finished recreating my portfolio using React. There aren&#8217;t very many visual changes apart from changing the hover effects a little. The site features a lot of repetitive content, such as portfolio items. React is good for this because I can create a component for the item which minimizes the amount of coding required. [&hellip;]\u003C\u002Fp>","I’ve just finished recreating my portfolio using React. There aren’t very many visual changes apart from changing the hover effects a little. The site features a lot of repetitive content, such as portfolio items. React is good for this because I can create a component for the item which minimizes the amount of coding required. […]","re-creating-my-portfolio-with-react",["Date","2020-02-03T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":465,"excerpt":466,"slug":469,"date":470,"modified":471,"readingTime":100,"acf":472,"tags":476,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Weather app",{"raw":467,"plain":468},"\u003Cp>My friend made a weather app so that they could learn APIs. I decided to fork it and take it a step further by experimenting with CSS Houdini, Variable Fonts, CSS Variables, and new browser APIs such as the Speech Synthesis API. Features This App uses experimental&nbsp;CSS Houdini&nbsp;features that are currently only supported in Google [&hellip;]\u003C\u002Fp>","My friend made a weather app so that they could learn APIs. I decided to fork it and take it a step further by experimenting with CSS Houdini, Variable Fonts, CSS Variables, and new browser APIs such as the Speech Synthesis API. Features This App uses experimental CSS Houdini features that are currently only supported in Google […]","weather-app",["Date","2020-02-01T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],{"project_url":473,"github":474,"icons":475},"https:\u002F\u002Fjoebailey26.github.io\u002FWeather-App\u002Findex.html","https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002FWeather-App",[200],[],{"title":478,"excerpt":479,"slug":482,"date":483,"modified":484,"readingTime":42,"acf":485,"tags":486,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"A new Portfolio with Vue.js – Joe Bailey Photography",{"raw":480,"plain":481},"\u003Cp>To mark the beginning of my second year at University I thought that I would try learning a new skill, namely Vue.js. I usually struggle to learn something if I don&#8217;t see any real practical application for it, but this time I figured I could turn my photography portfolio into a dynamic Vue.js enhanced page. [&hellip;]\u003C\u002Fp>","To mark the beginning of my second year at University I thought that I would try learning a new skill, namely Vue.js. I usually struggle to learn something if I don’t see any real practical application for it, but this time I figured I could turn my photography portfolio into a dynamic Vue.js enhanced page. […]","a-new-portfolio-with-vue-js",["Date","2019-12-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],[488,498,508,518,528,540,552,562,571,581],{"title":489,"excerpt":490,"slug":493,"date":494,"modified":495,"readingTime":100,"acf":496,"tags":497,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Cookie Consent – Joe Bailey Photography",{"raw":491,"plain":492},"\u003Cp>Over the past couple of months, I&#8217;ve added some Analytics software to my site such as Google Analytics and Facebook Pixel. As my website serves customers in the EU, the Cookie Law applies. I have used JavaScript to ensure that cookies are not fired until the user has explicitly accepted them on the website. A [&hellip;]\u003C\u002Fp>","Over the past couple of months, I’ve added some Analytics software to my site such as Google Analytics and Facebook Pixel. As my website serves customers in the EU, the Cookie Law applies. I have used JavaScript to ensure that cookies are not fired until the user has explicitly accepted them on the website. A […]","cookie-consent",["Date","2019-12-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":499,"excerpt":500,"slug":503,"date":504,"modified":505,"readingTime":42,"acf":506,"tags":507,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Re-doing my portfolio",{"raw":501,"plain":502},"\u003Cp>I built my web design portfolio site over the Christmas of 2018 and decided it needed a bit of a refresh during the summer. I got in touch with the @_tashhockey, the person behind Honest Feedback, to give my website a bit of a review. She made some really good points and brought to light [&hellip;]\u003C\u002Fp>","I built my web design portfolio site over the Christmas of 2018 and decided it needed a bit of a refresh during the summer. I got in touch with the @_tashhockey, the person behind Honest Feedback, to give my website a bit of a review. She made some really good points and brought to light […]","re-doing-my-portfolio",["Date","2019-10-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":509,"excerpt":510,"slug":513,"date":514,"modified":515,"readingTime":100,"acf":516,"tags":517,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Animated mobile menu",{"raw":511,"plain":512},"\u003Cp>In quite a few of my projects I&#8217;ve needed a quick and easy way of making a menu which scales onto mobile. I like the style that android apps have; the animated drawer, so I have replicated this. The menu is swipe aware using Hammer.js which means if you swipe right on mobile then the [&hellip;]\u003C\u002Fp>","In quite a few of my projects I’ve needed a quick and easy way of making a menu which scales onto mobile. I like the style that android apps have; the animated drawer, so I have replicated this. The menu is swipe aware using Hammer.js which means if you swipe right on mobile then the […]","animated-mobile-menu",["Date","2019-09-30T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":519,"excerpt":520,"slug":523,"date":524,"modified":525,"readingTime":100,"acf":526,"tags":527,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"No scroll whilst lightbox is open – Joe Bailey Photography",{"raw":521,"plain":522},"\u003Cp>I read the following article by CSS Tricks https:\u002F\u002Fcss-tricks.com\u002Fprevent-page-scrolling-when-a-modal-is-open\u002F and decided that my website shouldn&#8217;t scroll whilst the lightbox is shown, i.e. on the Blog and the Memories pages when an image is clicked. I use the Featherlight plugin on my Blog and the equivalent for the Memories page. I added the following CSS to [&hellip;]\u003C\u002Fp>","I read the following article by CSS Tricks https:\u002F\u002Fcss-tricks.com\u002Fprevent-page-scrolling-when-a-modal-is-open\u002F and decided that my website shouldn’t scroll whilst the lightbox is shown, i.e. on the Blog and the Memories pages when an image is clicked. I use the Featherlight plugin on my Blog and the equivalent for the Memories page. I added the following CSS to […]","no-scroll-whilst-lightbox-is-open",["Date","2019-08-01T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":529,"excerpt":530,"slug":533,"date":534,"modified":535,"readingTime":100,"acf":536,"tags":537,"author":18,"featuredMediaUrl":538,"featuredMedia":539},"Dark Mode – Joe Bailey Photography",{"raw":531,"plain":532},"\u003Cp>I read the following article: https:\u002F\u002Fwww.howtogeek.com\u002F434592\u002Fwhat%E2%80%99s-new-in-chrome-76-arriving-july-30th\u002F and was excited by &#8220;Automatic Dark Mode is Coming to Websites&#8221;. I decided to give it a shot. I read up on the Media Queries Level 5 spec and added the &#8220;prefers-color-scheme&#8221; media query to my CSS. I downloaded a copy of Chrome Canary to test the website, as [&hellip;]\u003C\u002Fp>","I read the following article: https:\u002F\u002Fwww.howtogeek.com\u002F434592\u002Fwhat%E2%80%99s-new-in-chrome-76-arriving-july-30th\u002F and was excited by “Automatic Dark Mode is Coming to Websites”. I decided to give it a shot. I read up on the Media Queries Level 5 spec and added the “prefers-color-scheme” media query to my CSS. I downloaded a copy of Chrome Canary to test the website, as […]","dark-mode",["Date","2019-07-29T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F18ef7e8b3ffaa78e6531a8e7db4678f61b89f836e42519209287c63e325266b7\u002F18ef7e8b3ffaa78e-dark-mode.jpg","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F18ef7e8b3ffaa78e6531a8e7db4678f61b89f836e42519209287c63e325266b7\u002F18ef7e8b3ffaa78e-dark-mode.jpg",{"title":541,"excerpt":542,"slug":545,"date":546,"modified":547,"readingTime":100,"acf":548,"tags":549,"author":18,"featuredMediaUrl":550,"featuredMedia":551},"Joe Bailey Photography is now a Progressive Web App",{"raw":543,"plain":544},"\u003Cp>Making my site work offline had been on my bucket list for a while. It was the last thing in Google Chrome&#8217;s Lighthouse test to complete. The site now has close to 100 scores across all areas in Google Chrome&#8217;s Lighthouse Audit. I read up on Service Workers on both Google Developers and MDN Web [&hellip;]\u003C\u002Fp>","Making my site work offline had been on my bucket list for a while. It was the last thing in Google Chrome’s Lighthouse test to complete. The site now has close to 100 scores across all areas in Google Chrome’s Lighthouse Audit. I read up on Service Workers on both Google Developers and MDN Web […]","joe-bailey-photography-is-now-a-progressive-web-app",["Date","2019-07-18T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F5464e472fd92822b761ed6e957448e480b6c12f6291d9ae23f168b154c37439d\u002F5464e472fd92822b-Untitled-1.jpg","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F5464e472fd92822b761ed6e957448e480b6c12f6291d9ae23f168b154c37439d\u002F5464e472fd92822b-Untitled-1.jpg",{"title":553,"excerpt":554,"slug":557,"date":558,"modified":559,"readingTime":100,"acf":560,"tags":561,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Data Flow Diagrams",{"raw":555,"plain":556},"\u003Cp>When we first started doing Data Flow Diagrams at the start of the semester I thought they were the worst thing in the world. However, as I came to understand them more and start to think about more real-world business problems that I was encountering such as creating a website for my Dad or as [&hellip;]\u003C\u002Fp>","When we first started doing Data Flow Diagrams at the start of the semester I thought they were the worst thing in the world. However, as I came to understand them more and start to think about more real-world business problems that I was encountering such as creating a website for my Dad or as […]","data-flow-diagrams",["Date","2019-04-19T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":412,"excerpt":563,"slug":566,"date":567,"modified":568,"readingTime":100,"acf":569,"tags":570,"author":18,"featuredMediaUrl":19,"featuredMedia":19},{"raw":564,"plain":565},"\u003Cp>During our Web Technologies practical lessons, we have to follow a set of instructions to create a website or simple script. The lecturer has hosted the notes for the unit on Firebase. I&#8217;d looked into Firebase before but couldn&#8217;t understand how to use it. However, when an extended task came up in lesson I gave [&hellip;]\u003C\u002Fp>","During our Web Technologies practical lessons, we have to follow a set of instructions to create a website or simple script. The lecturer has hosted the notes for the unit on Firebase. I’d looked into Firebase before but couldn’t understand how to use it. However, when an extended task came up in lesson I gave […]","firebase",["Date","2019-04-19T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":572,"excerpt":573,"slug":576,"date":577,"modified":578,"readingTime":100,"acf":579,"tags":580,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Angular, React, Vue, Node",{"raw":574,"plain":575},"\u003Cp>Whilst working on various projects this semester I&#8217;ve encountered the following technologies: Angular, React, Vue, and Node. I&#8217;ve experimented with them to some extent and found Node Package Manager quite useful. Initially, when I first heard about them I thought they were JavaScript Libraries like JQuery, however, they are far from it. Each technology is [&hellip;]\u003C\u002Fp>","Whilst working on various projects this semester I’ve encountered the following technologies: Angular, React, Vue, and Node. I’ve experimented with them to some extent and found Node Package Manager quite useful. Initially, when I first heard about them I thought they were JavaScript Libraries like JQuery, however, they are far from it. Each technology is […]","angular-react-vue-node",["Date","2019-04-19T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":582,"excerpt":583,"slug":586,"date":587,"modified":588,"readingTime":54,"acf":589,"tags":590,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"New Laptop, Deployment Manager, NAS and VPN",{"raw":584,"plain":585},"\u003Cp>I&#8217;d wanted to buy a new laptop for ages as mine was quite heavy and I wanted to take it to lectures, and store it in my bag but couldn&#8217;t. This meant I was looking for something quite light. I also wanted something powerful as I do a lot of media production and web development. [&hellip;]\u003C\u002Fp>","I’d wanted to buy a new laptop for ages as mine was quite heavy and I wanted to take it to lectures, and store it in my bag but couldn’t. This meant I was looking for something quite light. I also wanted something powerful as I do a lot of media production and web development. […]","new-laptop-deployment-manager-nas-and-vpn",["Date","2019-04-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],[592,602,614,626,636,646,656,666,676,686],{"title":593,"excerpt":594,"slug":597,"date":598,"modified":599,"readingTime":100,"acf":600,"tags":601,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Git",{"raw":595,"plain":596},"\u003Cp>As part of my studies at Solent, we were introduced to using Git in our workflow. Git is useful as it means mistakes can be corrected by rolling back the code to a version that worked. I&#8217;d come across this before at Fluid Studios Ltd. where they were using Git Kraken, however, I&#8217;d never really [&hellip;]\u003C\u002Fp>","As part of my studies at Solent, we were introduced to using Git in our workflow. Git is useful as it means mistakes can be corrected by rolling back the code to a version that worked. I’d come across this before at Fluid Studios Ltd. where they were using Git Kraken, however, I’d never really […]","git",["Date","2019-04-16T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":603,"excerpt":604,"slug":607,"date":608,"modified":609,"readingTime":100,"acf":610,"tags":613,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"No Thumbnails Gallery",{"raw":605,"plain":606},"\u003Cp>When creating my portfolio and memories page I needed a quick and easy way of creating galleries of images without having to code each individual image (there are over 3,000 images!). Also, I needed it without a thumbnail for each image. As far as I can tell there isn&#8217;t an easy option to do that. [&hellip;]\u003C\u002Fp>","When creating my portfolio and memories page I needed a quick and easy way of creating galleries of images without having to code each individual image (there are over 3,000 images!). Also, I needed it without a thumbnail for each image. As far as I can tell there isn’t an easy option to do that. […]","no-thumbnails-gallery",["Date","2019-02-06T00:00:00.000Z"],["Date","2026-11-08T00:00:00.000Z"],{"project_url":15,"github":611,"icons":612},"https:\u002F\u002Fgithub.com\u002Fjoebailey26\u002Fno-thumbnails-gallery",[362],[],{"title":615,"excerpt":616,"slug":619,"date":620,"modified":621,"readingTime":100,"acf":622,"tags":623,"author":18,"featuredMediaUrl":624,"featuredMedia":625},"Web Design Portfolio",{"raw":617,"plain":618},"\u003Cp>I&#8217;d been meaning to update my portfolio site for quite a while as I wasn&#8217;t really happy with the design. The long Christmas break gave me a chance to do just that. I was inspired by this template. In my lectures, we&#8217;d been learning about Figma and UX design. I wanted to use this redesign [&hellip;]\u003C\u002Fp>","I’d been meaning to update my portfolio site for quite a while as I wasn’t really happy with the design. The long Christmas break gave me a chance to do just that. I was inspired by this template. In my lectures, we’d been learning about Figma and UX design. I wanted to use this redesign […]","web-design-portfolio",["Date","2019-02-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F34a32b062918590e903c5210aa0d081d9960608cd1c70ece44100590aeafc4a6\u002F34a32b062918590e-Logo.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002F34a32b062918590e903c5210aa0d081d9960608cd1c70ece44100590aeafc4a6\u002F34a32b062918590e-Logo.png",{"title":627,"excerpt":628,"slug":631,"date":632,"modified":633,"readingTime":100,"acf":634,"tags":635,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Transferring my hosting package from 1and1 IONOS to iPage",{"raw":629,"plain":630},"\u003Cp>I think transferring hosting provider was the single greatest nightmare I&#8217;ve had in my life. I bought a few domains with 1and1, hoping to get SSL certificates that were advertised, however you only get one SSL certificate per contract. I&#8217;d have to create multiple contracts for all my domains, and then would not be able [&hellip;]\u003C\u002Fp>","I think transferring hosting provider was the single greatest nightmare I’ve had in my life. I bought a few domains with 1and1, hoping to get SSL certificates that were advertised, however you only get one SSL certificate per contract. I’d have to create multiple contracts for all my domains, and then would not be able […]","transferring-my-hosting-package-from-1and1-ionos-to-ipage",["Date","2019-02-06T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":637,"excerpt":638,"slug":641,"date":642,"modified":643,"readingTime":100,"acf":644,"tags":645,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Website Updates: Portfolio and Memories – Joe Bailey Photography",{"raw":639,"plain":640},"\u003Cp>After creating my Web Design portfolio site and transferring my hosting package I was in the mood to do some web design. I&#8217;d been meaning to add a portfolio to my photography site for a long while. Whilst making the photography portfolio I created some cool code to create a gallery of images which you [&hellip;]\u003C\u002Fp>","After creating my Web Design portfolio site and transferring my hosting package I was in the mood to do some web design. I’d been meaning to add a portfolio to my photography site for a long while. Whilst making the photography portfolio I created some cool code to create a gallery of images which you […]","website-updates-portfolio-and-memories",["Date","2019-02-01T00:00:00.000Z"],["Date","2026-11-03T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":647,"excerpt":648,"slug":651,"date":652,"modified":653,"readingTime":100,"acf":654,"tags":655,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Don’t forget your future self – Dan Benham",{"raw":649,"plain":650},"\u003Cp>I attended a talk by Dan Benham, set up by the university, which I found really interesting. He works for Studio Republic in Winchester. He was tired of working for corporate clients and started an ethical business to combat this. His business helps charities and other ethical entities with their creative tasks. An interesting question [&hellip;]\u003C\u002Fp>","I attended a talk by Dan Benham, set up by the university, which I found really interesting. He works for Studio Republic in Winchester. He was tired of working for corporate clients and started an ethical business to combat this. His business helps charities and other ethical entities with their creative tasks. An interesting question […]","dont-forget-your-future-self-dan-benham",["Date","2019-01-31T00:00:00.000Z"],["Date","2026-11-03T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":657,"excerpt":658,"slug":661,"date":662,"modified":663,"readingTime":54,"acf":664,"tags":665,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Web Components using PHP – Joe Bailey Photography",{"raw":659,"plain":660},"\u003Cp>In my Web Design and Development course, we touched on using web components and live style guides. This is the practice of having a set of components and styles that can be reused across your website. The advantage is that when something gets updated it rolls out across the whole site at the same time. [&hellip;]\u003C\u002Fp>","In my Web Design and Development course, we touched on using web components and live style guides. This is the practice of having a set of components and styles that can be reused across your website. The advantage is that when something gets updated it rolls out across the whole site at the same time. […]","web-components-using-php",["Date","2018-11-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":667,"excerpt":668,"slug":671,"date":672,"modified":673,"readingTime":100,"acf":674,"tags":675,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Wix Vs WordPress",{"raw":669,"plain":670},"\u003Cp>Now I&#8217;ve come across two instances of Wix in the past couple of months. Neither website was optimised for mobile. Wix has the option there, but it&#8217;s incredibly hard to use, you can change one thing and it will delete half the content on your site. The drag and drop editor is extremely slow, it&#8217;s [&hellip;]\u003C\u002Fp>","Now I’ve come across two instances of Wix in the past couple of months. Neither website was optimised for mobile. Wix has the option there, but it’s incredibly hard to use, you can change one thing and it will delete half the content on your site. The drag and drop editor is extremely slow, it’s […]","wix-vs-wordpress",["Date","2018-11-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":677,"excerpt":678,"slug":681,"date":682,"modified":683,"readingTime":42,"acf":684,"tags":685,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Flickr changes to free accounts – Joe Bailey Photography",{"raw":679,"plain":680},"\u003Cp>You might notice that my website uses Flickr to display most of the images. This is done by using an iframe of the Flickr slideshow. The reason I chose to use Flickr to display my images is that I didn&#8217;t have much experience coding at the time (I&#8217;m still not a code genius). It was [&hellip;]\u003C\u002Fp>","You might notice that my website uses Flickr to display most of the images. This is done by using an iframe of the Flickr slideshow. The reason I chose to use Flickr to display my images is that I didn’t have much experience coding at the time (I’m still not a code genius). It was […]","flickr-changes-to-free-accounts",["Date","2018-11-22T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":687,"excerpt":688,"slug":691,"date":692,"modified":693,"readingTime":100,"acf":694,"tags":695,"author":18,"featuredMediaUrl":696,"featuredMedia":697},"Logo design for a Web Developer",{"raw":689,"plain":690},"\u003Cp>My first project at university was to write a report on how I designed a set of logos to brand myself as a web developer. We had to include research, feedback and final designs. I got a C1 on this report as I found it quite hard being the first one I&#8217;ve done at university. [&hellip;]\u003C\u002Fp>","My first project at university was to write a report on how I designed a set of logos to brand myself as a web developer. We had to include research, feedback and final designs. I got a C1 on this report as I found it quite hard being the first one I’ve done at university. […]","logo-design-for-a-web-developer",["Date","2018-11-09T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fbfc46bfee4b29cd76ba47fce9df8298461166dcf1625803ae0fda5cf85803866\u002Fbfc46bfee4b29cd7-1Artboard-1joe.png","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fbfc46bfee4b29cd76ba47fce9df8298461166dcf1625803ae0fda5cf85803866\u002Fbfc46bfee4b29cd7-1Artboard-1joe.png",[699,709,719,729,739,749,763,773],{"title":700,"excerpt":701,"slug":704,"date":705,"modified":706,"readingTime":100,"acf":707,"tags":708,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"rankingCoach",{"raw":702,"plain":703},"\u003Cp>I attended a workshop in Hotel Mercure Southampton Centre Dolphin on rankingCoach by Alasdair Stone. It was a very interesting event and we learnt about how to optimize website for search engines. We also learnt how to use tools such as Google My Business. I came away from the event with a lot of notes [&hellip;]\u003C\u002Fp>","I attended a workshop in Hotel Mercure Southampton Centre Dolphin on rankingCoach by Alasdair Stone. It was a very interesting event and we learnt about how to optimize website for search engines. We also learnt how to use tools such as Google My Business. I came away from the event with a lot of notes […]","rankingcoach",["Date","2018-11-08T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":710,"excerpt":711,"slug":714,"date":715,"modified":716,"readingTime":42,"acf":717,"tags":718,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Material Design",{"raw":712,"plain":713},"\u003Cp>“Make beautiful products, faster. Material is a design system – backed by open-source code – that helps teams build digital experiences” Material.io Material is a design language created by Google in 2014 for the Android platform. It has unified Android apps under a single design format. This has helped to give the Android platform a [&hellip;]\u003C\u002Fp>","“Make beautiful products, faster. Material is a design system – backed by open-source code – that helps teams build digital experiences” Material.io Material is a design language created by Google in 2014 for the Android platform. It has unified Android apps under a single design format. This has helped to give the Android platform a […]","material-design",["Date","2018-10-17T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":720,"excerpt":721,"slug":724,"date":725,"modified":726,"readingTime":100,"acf":727,"tags":728,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Barcamp Southampton",{"raw":722,"plain":723},"\u003Cp>I went to a Barcamp in Southampton, which consists of people giving talks on things they find interesting, with a heavy bias on technology. The normal talks last 45 minutes to an hour. They also have an opportunity to give lightning talks after lunch which last about 10 minutes and can be about anything. I [&hellip;]\u003C\u002Fp>","I went to a Barcamp in Southampton, which consists of people giving talks on things they find interesting, with a heavy bias on technology. The normal talks last 45 minutes to an hour. They also have an opportunity to give lightning talks after lunch which last about 10 minutes and can be about anything. I […]","barcamp-soton",["Date","2018-10-07T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":730,"excerpt":731,"slug":734,"date":735,"modified":736,"readingTime":42,"acf":737,"tags":738,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"CSS Grid",{"raw":732,"plain":733},"\u003Cp>&#8220;CSS Grid Layout is shaping up to be the layout tool we’ve always wanted on the web.&#8221; Stacy Kvernmo (September 19, 2016) In the early days of the web, developers laid things out using tables. Tables are only designed for tabular data and developers were splitting GIFs up to lay them out and create visually [&hellip;]\u003C\u002Fp>","“CSS Grid Layout is shaping up to be the layout tool we’ve always wanted on the web.” Stacy Kvernmo (September 19, 2016) In the early days of the web, developers laid things out using tables. Tables are only designed for tabular data and developers were splitting GIFs up to lay them out and create visually […]","css-grid",["Date","2018-10-04T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":740,"excerpt":741,"slug":744,"date":745,"modified":746,"readingTime":100,"acf":747,"tags":748,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Web Design and Development",{"raw":742,"plain":743},"\u003Cp>I&#8217;ve just started my first proper job in the Web Design and Development industry at Fluid Studios Ltd&nbsp;and it&#8217;s going really well. I&#8217;m also starting to get ready for university, the next big exciting chapter in my life.\u003C\u002Fp>","I’ve just started my first proper job in the Web Design and Development industry at Fluid Studios Ltd and it’s going really well. I’m also starting to get ready for university, the next big exciting chapter in my life.","web-design-and-development",["Date","2018-06-08T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":750,"excerpt":751,"slug":754,"date":755,"modified":756,"readingTime":100,"acf":757,"tags":760,"author":18,"featuredMediaUrl":761,"featuredMedia":762},"joebailey.xyz",{"raw":752,"plain":753},"\u003Cp>I&#8217;ve started creating a site to showcase my work as a web design professional. Once finished it will be live at joebailey.xyz I&#8217;m not really feeling it as much as my photography website, I don&#8217;t think the design flows that well, and it doesn&#8217;t really optimize for mobile all that well either. I think maybe [&hellip;]\u003C\u002Fp>","I’ve started creating a site to showcase my work as a web design professional. Once finished it will be live at joebailey.xyz I’m not really feeling it as much as my photography website, I don’t think the design flows that well, and it doesn’t really optimize for mobile all that well either. I think maybe […]","joebailey-xyz",["Date","2018-03-21T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":758},[426,200,759],"Netlify",[],"https:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe28b08c407668af2eb67e835a3986a145fd2c94feace17010d6a8d860d780278\u002Fe28b08c407668af2-Logo.jpg","https:\u002F\u002Fjoebailey.xyz\u002Fcdn-cgi\u002Fimage\u002Fformat=auto,quality=80,fit=scale-down,width=1200\u002Fhttps:\u002F\u002Fcms.joebailey.xyz\u002Fmedia\u002Fe28b08c407668af2eb67e835a3986a145fd2c94feace17010d6a8d860d780278\u002Fe28b08c407668af2-Logo.jpg",{"title":764,"excerpt":765,"slug":768,"date":769,"modified":770,"readingTime":100,"acf":771,"tags":772,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"New Blog – Joe Bailey Photography",{"raw":766,"plain":767},"\u003Cp>I&#8217;ve finally started phase 3 of the redesign of my website. Phase one was to create it, learning lots of code along the way to prepare me for my University course, and also to give me the creative freedom that I hadn&#8217;t yet been able to achieve with various website builders. During phase 2 I [&hellip;]\u003C\u002Fp>","I’ve finally started phase 3 of the redesign of my website. Phase one was to create it, learning lots of code along the way to prepare me for my University course, and also to give me the creative freedom that I hadn’t yet been able to achieve with various website builders. During phase 2 I […]","new-blog",["Date","2018-03-21T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],{"title":774,"excerpt":775,"slug":778,"date":779,"modified":780,"readingTime":100,"acf":781,"tags":782,"author":18,"featuredMediaUrl":19,"featuredMedia":19},"Welcome – Joe Bailey Photography",{"raw":776,"plain":777},"\u003Cp>Hello everyone, Welcome to my new website. Sorry for the delay, it&#8217;s been a year in the making and there&#8217;s still much to do, like implement a store and add my backlog of images to the gallery. If you encounter any problems whilst browsing, please don&#8217;t hesitate to contact me, and I&#8217;ll see what I [&hellip;]\u003C\u002Fp>","Hello everyone, Welcome to my new website. Sorry for the delay, it’s been a year in the making and there’s still much to do, like implement a store and add my backlog of images to the gallery. If you encounter any problems whilst browsing, please don’t hesitate to contact me, and I’ll see what I […]","welcome",["Date","2018-01-20T00:00:00.000Z"],["Date","2026-10-22T00:00:00.000Z"],{"project_url":15,"github":15,"icons":15},[],1794352902033]