Articles in the year 2021

Goodbye Forge, Hello Ploi

2 years ago Thu, May 6, 2021

When it first launched, Laravel Forge was the easiest and cheapest way to deploy a Laravel application onto a custom server. Recently, after repeatedly being presented with upgrade banners for new features, I decided to investigate the alternatives before committing to a higher fee. Happily, I stumbled upon Ploi.

At first I was skeptical that anyone could compete with the Laravel Core team who manage the established and stable product that is Laravel Forge, but over a few short hours I was increasingly convinced that Ploi was not only a suitable alternative, but hands down the better offering. Here's what finally changed my mind, made me switch all my sites and end my Forge subscription.

When it first launched, Laravel Forge was priced at $10 a month for unlimited servers, sites and services. This was an amazing and probably somewhat underpriced offering. It was incredible to be able to launch a Laravel site with a few clicks and forget about server management entirely. No more digging around in Nginx config files and hours spent installing the latest version of this or that version of PHP. Over time, more features were added for team functionality. I didn't upgrade because I didn't need access to these features. Later, the basic subscription price was increased slightly for new users, but the fee for users on existing plans remained the same.

In the last year or so, however, certain new features such as server monitoring and database backups were added but only made available to users on a premium tier at $39 a month. This is quite a steep increase for features that have now become commonplace on other services. Nevertheless, this is a price that would be well worth paying if it werent for two simple reasons.

First, instead of being hidden in the settings, these additional features are presented to all users irrespective of the tier they were on. This means that as you explore the UI, you are continually presented with useless pages for features you cannot use and encouraged somewhat relentlessly to upgrade to a higher tier.

Second, a lot has changed in the few years since Laravel Forge was launched. It is now much easier to deploy sites directly to cloud providers such as AWS and Digital Ocean. Furthermore, there are a number of competitors that offer the same feature set and more for a fraction of the price.

After a quick comparison of the alternatives, I stumbled upon Ploi. It makes a great first impression and gets better and better from there. First, its fresh design makes for a welcome break from Forge's simplistic user interface which despite being improved over the years has started to feel a bit tired. Its features are well organised, searchable and accessible and it's help pages are useful and comprehensive. Next, its pricing is cheaper than Forge on every tier and offers all Forge features for less than half the price. It is intuitive and easy to use and guides you to make full use of the featurews available to you. Even better, there is no mention of upgrading unless you are looking to do so.

Finally, when you are ready to pay a little bit more, you gain access to a rich array of features which are simply not available on Laravel Forge, such as:

  • Site Monitoring
  • File Browsing
  • Status Pages
  • The ability to suspend sites with the click of a button
  • Zero Downtime deployment

All of this combined, made it a no brainer for me. Much as Laravel Forge has served me well over recent years, it was time to move on. I hope that this increased competition will make both products better and can't wait for all the quality of life goodies that we can look forward to over the next few years.

If you're convinced or simply want to try Ploi for yourself, you can sign up for a free trial with no credit card required.

Thank you for reading this article.

If you've made it this far, you might like to connect with me on 𝕏 where I post similar content and interact with like-minded people. If this article was helpful to you I'd really appreciate it if you would consider buying me a coffee.
Continue Reading

Meta Tags, Link Tags And Web Manifests

2 years ago Wed, Feb 24, 2021

Every time I make a new site, I spend a significant amount of time adding meta and link tags to the layout. I do this to improve SEO but also to control the way the site is rendered in different browsers, share sheets and operating systems. I often find myself looking up details which I have researched in the past. This article will list all the tags I use on this and other sites. I hope it will save you (and future me) a lot of time.

#The Basics

  • Meta tags represent metadata that cannot be represented by other HTML meta-related elements such as <title>, <script>, or <link>.
  • Link tags define relationships between the current document and external resources.

All the tags described in this article should go in the <head> tag of your site. Depending on your setup, it is probably best to have a sensible default in your layout file, that can be overwriten with more specific content on dedicated pages of your site. In this way, static pages like your home page will have content related to your site as a whole, whereas specific pages for articles, recipes etc will have more relevant content.


The title tag defines the title for the page. This will be shown in the browser's title bar, address bar or tab. It will also be used for the default name of a bookmark, title in search engine results, share sheets and rich links.

<title>Carl Cassar</title>


This meta tag declares the document's charset or character encoding. As it happens, UTF-8 is the only valid encoding for HTML5 documents. Make sure to place this at the start of the head tag as character encoding elements must be present within the first 1024 bytes of the document.

UTF-8 is a character set defined by the Unicode Consortium that develops the Unicode Standard. A character from UTF-8 can be 1-4 bytes long and can represent any character in the Unicode Standard.

<meta charset="utf-8">


The viewport meta tag was introduced by Apple to let web developers control the viewport's size and scale, but is now supported by many other browsers. This tag can be used to set the width of the viewport and the initial scale of the viewport in relation to the device.

<meta name="viewport" content="width=device-width, initial-scale=1">

It is also possible to prevent the user from scaling the viewport by using the property content="user-scalable=no", however this will probably lead to a worse user experience as most people have come to expect that they can scale a website to "zoom in", especially on mobile devices.


As its name implies, the Description Meta tag is used to add a short textual description for the current page. This tag used to be a lot more important for SEO before search engines took the actual content of the page into consideration, but it is still useful for Bookmarks, Rich Links and SERPs (Search Engine Result Pages).

Try to keep the description for a page to between 50–160 characters, since Google and others often truncate longer descriptions. This is your opportunity to advertise and summarise the content of your page, so make sure the description is concise and tells your audience what to expect. Don't try to be clever and stuff your description with search keywords as search engines have become wise to this trick and may actually harm your SEO rankings.

<meta name="description" content="Carl Cassar's Blog">


The keywords meta tag allows you add a comma-separated list of keywords that encapsulate the content on your page.

<meta name="keywords" content="PHP, Laravel, JavaScript, Vue">

Just like with the description tag, search engines can detect "keyword stuffing", but this doesn't mean that tag should be ommitted. Your best bet is to be honest and truthful, adding a few choice keywords (3-5) that accurately reflect the content of your page.


This meta tag quite simply specifies the author for the content on that page.

<meta name="author" content="Carl Cassar">

#Open Graph

The stated purpose of Open Graph tags is to enable any web page to become a rich object in a social graph. In reality, this means that a web page can specify a title, description, url, keywords, images and more that will declare how the website should be displayed in rich links on other sites and applications.

There are many open graph structured properites that you can add to your site. These are the ones that I find most useful and would reccomend as a minimum. The more you add, the more control you are likely to have over how your site is presented to users in other contexts.

There are many online tools that can help you generate open graph tags for your own site, by guiding you to fill in various fields and upload the relevant images. I find particularly useful.

<meta property="og:title" content="Carl Cassar" />
<meta property="og:description" content="Carl Cassar's Blog" />
<meta property="og:url" content="" />
<meta property="og:type" content="website" />
<meta property="og:updated_time" content="2021-02-24T12:52:54+00:00" />

<meta property="og:image" content="path/to/image" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="1200" />

<meta property="og:image" content="path/to/image" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="600" />


While many sites such as Facebook, Pinterest, LinkedIn and Google use Open Graph tags to extract rich content from your site, Twitter has opted to extend this standard with its own system and therefore requires addition meta tags.

These are the ones that I use on my own sites:

<meta name="twitter:site" content="@carlcassar" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:creator" content="@carlcassar" />

#Theme Color

This tag can specify the overall theme colour for your site. It is used by browsers for various UI elements and can be a great way to show your users that you care about the details.

<meta property="theme-color" content="#ffffff" />

#Windows Tiles

A windows tile is an image that represents your app on the Windows start screen.

If a tile is not specified in the meta tags for your site, Windows will use the image from the favicon, but this could lead to low resolution or blurry images.

These are the meta tags I use to add tiles to my sites:

<meta property="msapplication-TileColor" content="#ed8936" />
<meta property="msapplication-TileImage" content="path/to/image" />

If you prefer not to add many meta tags for different properties, you can use one meta tag that links to a browser config xml file:

<meta name="msapplication-config" content="browserconfig.xml" />
<?xml version="1.0" encoding="utf-8"?>
            <square70x70logo src="path/to/image"/>
            <square150x150logo src="path/to/image"/>
            <wide310x150logo src="path/to/image"/>
            <square310x310logo src="path/to/image"/>


As with Windows, there are a number of meta tags specific to iOS.

These are the two tags I am currently using on my sites:

<meta name="apple-mobile-web-app-capable" content="yes">
<meta property="apple-mobile-web-app-status-bar-style" content="default" />

The first tag indicates that the site can be used as a mobile web app, while the second specifies the style to be used for the status bar in an iOS web app.


Favicons are small icons that are used by the browser for tabs, bookmark bars, window bars, address bars and other UI elements as a placeholder for your site. It's good to have a number of different favicon sizes and formats to suit the needs of different browsers.

These are the ones I'm currently using:

<link href="path/to/image.ico" rel="icon" type="image/x-icon">
<link href="path/to/image.png" rel="icon" type="image/png">
<link href="path/to/image.png" rel="icon" type="image/png">
<link href="path/to/image.svg" rel="mask-icon" type="image/svg" sizes="693x693">
<link href="path/to/image.svg" rel="apple-touch-icon" type="image/svg" sizes="180x180">

As with meta tags, there are many online favicon generators.

#Web Manifest

A web app manifest is a JSON text file that gives information about a web application. This file can be downloaded and used to present the site as a native app.

I use a web manifest for my sites, including this blog so users can add a bookmark to their home screen with a nice logo and description. They can then quickly open this 'app' to see the site without browser bars and other distractions.

To add a web manifest, first create a web manifest file, site.webmanifest, in the root of your public directory:

    "name": "Carl Cassar",
    "short_name": "Carl Cassar",
    "start_url": "/",
    "icons": [
            "src": "/favicons/android-chrome-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
            "src": "/favicons/android-chrome-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
          "src": "/favicons/apple-touch-icon.png",
          "sizes": "180x180",
          "type": "image/png"
    "theme_color": "#ffffff",
    "background_color": "#ffffff",
    "display": "standalone"

and then add a link to this file in the head of your site:

<link href="path/to/site.webmanifest" rel="manifest">


I hope you found this article useful. I intend for it to be a work in progress and will update it whenever I learn something new or a adopt a new practice. If you spot anything wrong or missing, I'd love it if you could leave a comment below.

Thank you for reading this article.

If you've made it this far, you might like to connect with me on 𝕏 where I post similar content and interact with like-minded people. If this article was helpful to you I'd really appreciate it if you would consider buying me a coffee.
Continue Reading

How To Build The Imagick Php Extension From Source

2 years ago Tue, Feb 23, 2021

Update: This instructions in this article should no longer be necessary as you can once again install imagick via pecl:

pecl install imagick

If you are still having issues, I would recommend this excellent article by Andrea Olivato.

At the time of writing, the PHP8 compatible version of the Imagick extension has not yet been released, which means it is not available via PECL.

After a quick Google search, I found this excellent article by Freek Van der Herten explaining how to build the php extension from the master branch, which already seems to work with PHP 8.

After I followed Freek's instructions, I noticed that the extention was missing a package version number that is ordinarily populated automatically when the extension is built via the PECL installer. As it turns out, one of my sites also relies on Laravel DOMPDF which requires the Imagick version number to be present for it to work correctly.

Let's go over the steps described by Freek with some additional context and code snippets.

  1. Clone the repository to your local development directory:
git clone
  1. Open the php_imagick.h located in the root of the imagick directory. Locate the following line:

and replace "@PACKAGE_VERSION@" with the latest released version. In my case this was 3.4.4, so I modified the line to this:

#define PHP_IMAGICK_VERSION    "3.4.4"
  1. Follow the guide to compile the extension.
# Navigate to the cloned directory
cd /path/to/imagick

# Prepare the build environment for a PHP extension.

# Run a script to make sure your system has the proper dependencies to compile from source.

# Compile the extension.
  1. Locate and copy the newly created extension which can be found in the modules directory inside the cloned imagick directory:
  1. Use the following command to find the directory in which your PHP version expects to find extensions:
php -i | grep extension_dir

php -i prints all php information. This output is piped (sent) to the grep command which searches the output for the given keyword - extension_dir in this case.

This command should return something like this:

extension_dir => /usr/local/lib/php/pecl/20200930 => /usr/local/lib/php/pecl/20200930

Copy the file to this directory.

  1. Use the php --ini command to find the loaded configuration file for your php installation. In my case, this was:

Open this file in your preferred code editor and add the following line anywhere in the file:


This will instruct php to load the imagick extension.

All being well, the Imagick extension should now be installed. You might need to restart the PHP service for this change to be registered. In my case, as a Laravel Valet user, I restarted Valet with the following command:

valet restart

Finally, you can use the following command to make sure the extension is loaded correctly:

php -i | grep imagick

This should result in the following output:

imagick module => enabled

I hope this works for you as it did for me. Once again, my thanks go to Freek for most of these instructions and to Danack, the maintaner of the PHP Imagick extension. Please consider sponsoring him if your work depends on the Imagick extension.

Thank you for reading this article.

If you've made it this far, you might like to connect with me on 𝕏 where I post similar content and interact with like-minded people. If this article was helpful to you I'd really appreciate it if you would consider buying me a coffee.
Continue Reading