<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>James Mills</title>
	<atom:link href="https://jamesmills.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>https://jamesmills.co.uk</link>
	<description>James Mills, passionate web consultant.</description>
	<lastBuildDate>Wed, 14 Sep 2022 06:46:27 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.4.19</generator>
<site xmlns="com-wordpress:feed-additions:1">156597337</site>	<item>
		<title>Removing foreign keys from a Laravel application</title>
		<link>https://jamesmills.co.uk/2022/09/14/removing-foreign-keys-from-a-laravel-application/</link>
					<comments>https://jamesmills.co.uk/2022/09/14/removing-foreign-keys-from-a-laravel-application/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Wed, 14 Sep 2022 06:16:00 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[foreign keys]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[mysql]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1313</guid>

					<description><![CDATA[I currently use Digital Ocean&#8217;s managed database for my primary database but I wanted to try out Planet Scale. When migrating a database over to Planet Scale you cannot use Foreign Keys. This got me thinking about a way to automatically generate a migration file to drop all foreign keys. If you want to jump [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>I currently use Digital Ocean&#8217;s managed database for my primary database but I wanted to try out <a href="https://planetscale.com/" class="rank-math-link" target="_blank" rel="noopener">Planet Scale</a>. When migrating a database over to Planet Scale you cannot use Foreign Keys. This got me thinking about a way to automatically generate a migration file to drop all foreign keys. </p>



<p>If you want to jump the intro and background you can jump directly to the good stuff here <a href="#building-a-laravel-migration-to-drop-all-foreign-keys" class="rank-math-link">building a Laravel migration to drop all Foreign Keys.</a></p>



<hr class="wp-block-separator"/>



<p>I&#8217;m not sure when it first started, probably in my advanced database class when studying Information Technology at Teesside University, but someone told me to include foreign keys whenever I can. It&#8217;s been ingrained in my mind for as long as I can remember.</p>



<p>I then started working with migrations in Laravel and I soon became a fan of this simple one-liner to add a column, index and foreign key to to a table using a migration.</p>



<pre class="wp-block-code"><code>Schema::table('sites', function (Blueprint $table) {
    // Referencing the column and table yourself
    $table->foreign('theme_id')->references('id')->on('themes');

    // Using Laravel and it's magic
    $table->foreignId('themes')->index()->constrained()->cascadeOnDelete();
});</code></pre>



<p>I&#8217;ve never really understood what benefits a foreign key gives you. To me, the most important thing in these types of columns is the index, but you can add that separately. </p>



<pre class="wp-block-code"><code>Schema::table('sites', function (Blueprint $table) {
    $table->bigInteger('theme_id')->index();
});</code></pre>



<p>I do like the fact that when you&#8217;re browsing tables in software like <a href="https://tableplus.com/" class="rank-math-link" target="_blank" rel="noopener">TablePlus</a> that you get a convenient arrow next to the foreign key which you can click and it will take you to the references row/table. I also like the fact that when you create Entity Relationship Diagrams (ERD) that it can automatically detect relationships and draw lines between tables.</p>



<h2>Planet Scale &#8211; Modern Databases</h2>



<p>I&#8217;m sure you&#8217;ve all heard about the hype around <a href="https://planetscale.com/" class="rank-math-link" target="_blank" rel="noopener">Planet Scale</a>. </p>



<blockquote class="wp-block-quote"><p><em>&#8220;The MySQL-compatible serverless database platform&#8221;</em>. </p></blockquote>



<p>They&#8217;ve recently introduced a hugely powerful migration process which gives you access to a <a href="https://planetscale.com/blog/import-your-mysql-data-to-planetscale" class="rank-math-link" target="_blank" rel="noopener">simple and easy zero-downtime migration</a> from your current database into Planet Scales solution.</p>



<p>I&#8217;ve been intrigued to see what performance benefits I could get from moving so this week I decided to have a play. I use Digital Ocean managed database so I cloned my primary database and started the process of migrating this over to Planet Scale. I anticipated that I may need to adjust things on my primary before I could do the migration so I wanted to be able to use a cloned version.</p>



<p>The setup process for Planet Scale is remarkably easy and they guide you through the migration process every step of the way. However, I hit my first stumbling block quite quickly. I was greated with a message informing me that <a href="https://planetscale.com/docs/learn/operating-without-foreign-key-constraints" class="rank-math-link" target="_blank" rel="noopener">Planet Scale does not support foreign keys</a>.</p>



<blockquote class="wp-block-quote"><p>To support scaling across multiple database servers, <strong>PlanetScale does not allow the use of foreign key constraints</strong>, which are normally used in relational databases to enforce relationships between data in different tables, and asks users to handle this manually in their applications.</p></blockquote>



<p>I&#8217;m sure someone could give us a detailed explanation for why this is but I&#8217;m not that person. One thing was certain, if I wanted to continue, I needed to remove the foreign keys from my database.</p>



<h2>Removing Foreign Keys from MySQL </h2>



<p>It&#8217;s actually quite easy to drop a foreign key. You just need to know the reference name and then just run</p>



<pre class="wp-block-code"><code>ALTER TABLE sites DROP FOREIGN KEY sites_theme_id_foreign;</code></pre>



<p>There is also a <a href="https://laravel.com/docs/9.x/migrations#foreign-key-constraints" class="rank-math-link" target="_blank" rel="noopener">Laravel helper</a> which you can add to a migration to do this.</p>



<pre class="wp-block-code"><code>Schema::table('sites', function (Blueprint $table) {
    // If you want to use the index name
    $table->dropForeign('sites_theme_id_foreign');

    // If you want Laravel to do it's magic based on the column name
    $table->dropForeign(&#91;'sites_theme_id']);
});</code></pre>



<h2 id="building-a-laravel-migration-to-drop-all-foreign-keys">Building a Laravel migration to drop all Foreign Keys</h2>



<p>I really didn&#8217;t want to have to dig through all my database tables to work out which ones had foreign keys and then hand write each table and column into a new migration. So I thought I&#8217;d write something to do it for me. </p>



<p>I&#8217;ve built a very simple Laravel Command that you can run. It will connect to your database, get information on all the tables and forging keys and then loop through and spit out some formatted <code>dropForeign</code> stuff for you into a <code>storage/app/migration_stuff.txt</code> file.</p>



<p>The source for the below is also available in a <a href="https://gist.github.com/jamesmills/07182fd20fc03c90e79e815754984197" class="rank-math-link" target="_blank" rel="noopener">GitHub Gist</a></p>



<pre class="wp-block-code"><code>&lt;?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class GenerateDropForeignKeyMigration extends Command
{
    protected $signature = 'migration';

    protected $description = 'Command description';

    public function handle()
    {
        $data = DB::select(
            "
            SELECT
              TABLE_NAME,
              COLUMN_NAME,
              CONSTRAINT_NAME,
              REFERENCED_TABLE_NAME,
              REFERENCED_COLUMN_NAME
            FROM
              INFORMATION_SCHEMA.KEY_COLUMN_USAGE
            WHERE
              REFERENCED_TABLE_SCHEMA = ?",
            &#91;config('database.connections.mysql.database')]
        );

        $results = collect($data)->groupBy('TABLE_NAME');

        $text = '';

        foreach ($results as $table => $data) {
            $text .= sprintf(
                "Schema::table('%s', function (Blueprint \$table) {
",
                $table
            );

            foreach ($data as $item) {
                $text .= sprintf("    \$table->dropForeign('%s');\n", $item->CONSTRAINT_NAME);
            }

            $text .= "});\n";
        }

        Storage::put('migration_stuff.txt', $text);
    }
}</code></pre>



<p>This dumps something like the below in&nbsp;<code>storage/app/migration_stuff.txt</code></p>



<pre class="wp-block-code"><code>Schema::table('team_invitations', function (Blueprint $table) {
    $table->dropForeign('team_invitations_team_id_foreign');
});
Schema::table('placement_webhook', function (Blueprint $table) {
    $table->dropForeign('placement_webhook_placement_id_foreign');
    $table->dropForeign('placement_webhook_webhook_id_foreign');
});
Schema::table('site_partner_buckets', function (Blueprint $table) {
    $table->dropForeign('site_partner_buckets_bucket_id_foreign');
    $table->dropForeign('site_partner_buckets_partner_id_foreign');
    $table->dropForeign('site_partner_buckets_site_id_foreign');
});</code></pre>



<p>I have thought about making this a package but I honestly don&#8217;t have the time right now so if you feel like you could package this up then please feel free!</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2022/09/14/removing-foreign-keys-from-a-laravel-application/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1313</post-id>	</item>
		<item>
		<title>Applications to install on a new Macbook Pro</title>
		<link>https://jamesmills.co.uk/2021/06/21/applications-to-install-on-a-new-macbook-pro/</link>
					<comments>https://jamesmills.co.uk/2021/06/21/applications-to-install-on-a-new-macbook-pro/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Mon, 21 Jun 2021 12:28:20 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code & Development]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1291</guid>

					<description><![CDATA[I know everyone does these posts but I always find it helpful to document this sort of thing just in case it&#8217;s useful to others. I&#8217;ve recently for a MacBook Pro 13&#8243; M1. I&#8217;m going to add what I install (in no particular order) to this page. Let me know if it&#8217;s helpful. 1Password Been [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>I know everyone does these posts but I always find it helpful to document this sort of thing just in case it&#8217;s useful to others.</p>



<p>I&#8217;ve recently for a MacBook Pro 13&#8243; M1. I&#8217;m going to add what I install (in no particular order) to this page. Let me know if it&#8217;s helpful.</p>



<h2><a href="https://1password.com" class="rank-math-link" target="_blank" rel="noopener">1Password</a></h2>



<p>Been using this for years now. It&#8217;s got everything in it. I don&#8217;t even think about passwords anymore, I just use a unique one for each service and store it in 1Password. With convenient apps for all devices and helpful browser extensions, it&#8217;s a no-brainer for me.</p>



<h2><a href="https://sparkmailapp.com" class="rank-math-link" target="_blank" rel="noopener">Spark Mail</a></h2>



<p>There are hundreds of email clients out there and everyone has their own personal preference about how email should work. I&#8217;m a huge fan of Spark Mail. It just works. I love the &#8220;<a href="https://sparkmailapp.com/features/smart_inbox" class="rank-math-link" target="_blank" rel="noopener">Smart Inbox</a>&#8221; which helps me see at a glance what&#8217;s new and important to me. The other thing I like is that you create one login for Spark and then once you sign into that on Laptop, iPhone and iPad everything is in sync.</p>



<h2><a href="https://www.dropbox.com" class="rank-math-link" target="_blank" rel="noopener">Dropbox</a></h2>



<p>Since the very early days, I&#8217;ve been using DropBox. I use it for everything and anything. The only thing that&#8217;s not in DropBox is the code that I have in Git. Passport copies, travel insurance, receipts for expensive items, photos of childhood memories&#8230; it&#8217;s all in DropBox. Synced and accessible from anywhere. It&#8217;s a no-brainer. </p>



<h2><a href="https://slack.com/" class="rank-math-link" target="_blank" rel="noopener">Slack</a></h2>



<p>Some love it some hate it. I love it. Slacks the core of all my communication at Successful Media and I try and invite as many external partners into Slack as possible. I create channels for almost everything. We have project channels (shared with a partner) and I have channels for deployment notifications, website uptime issues, etc.</p>



<h2>Other Chat Clients</h2>



<p>I hate that I have to install, manage and use so many differnt chat apps but that&#8217;s the world we live in. Here are the others:</p>



<ol><li><a href="https://www.skype.com/" class="rank-math-link" target="_blank" rel="noopener">Skype</a> &#8211; Business chat with people I cannot connect with in Slack</li><li><a href="https://telegram.org/" class="rank-math-link" target="_blank" rel="noopener">Telegram</a> &#8211; Useful for notifications (&amp; people who don&#8217;t like Slack ;-))</li></ol>



<h2><a href="https://zoom.us/" class="rank-math-link" target="_blank" rel="noopener">Zoom</a></h2>



<p>We all need it. Much prefer this than Google Hangouts and MS Teams etc. Once you set your preferences to match your needs it&#8217;s so quick and easy to &#8220;jump on a call&#8221;.</p>



<h2><a href="https://www.git-tower.com/" class="rank-math-link" target="_blank" rel="noopener">GitTower</a></h2>



<p>I know people like to stay retro and use the CLI for Git but I&#8217;ve never been able to get into that. I&#8217;m a huge fan of using something with a GUI. I&#8217;ve tried a few over the years but GitTower is the winner for me. I&#8217;ve paid for a license for this for a long time. It does what it says on the tin. Great product. </p>



<h2><a href="https://www.jetbrains.com/phpstorm/" class="rank-math-link" target="_blank" rel="noopener">PHPStorm</a></h2>



<p>Use what you feel comfortable with and certainly always go for the best tool for the job. For me that&#8217;s PHPStorm. I install it via the JetBrains Toolbox. Happy to be trying out the Apple Silicone version, hoping to see things feel slightly more responsive. </p>



<h2><a href="https://manytricks.com/moom/" class="rank-math-link" target="_blank" rel="noopener">Moom</a></h2>



<p>If you&#8217;re a little OCD about keeping your open windows organized then Moom will help. Easily snap windows to grids etc. Simple. Does what it says on the tin. </p>



<h2><a href="https://evernote.com/" class="rank-math-link" target="_blank" rel="noopener">Evernote</a></h2>



<p>I should probably look at using the Apple Notes but quite frankly I just love the simplicity of Evernote. I&#8217;ve been using it since 2010 and so I have so much data in there. Quite literately everything gets dumped into Evernote. Everything including things like planning, documentation, settings, how-to, reminders, meeting agendas, follow-up notes, and most importantly random brain dumps!</p>



<h2><a href="https://www.postman.com/" class="rank-math-link" target="_blank" rel="noopener">Postman</a></h2>



<p>A fantastic local tool to test and consume API&#8217;s. Great for requests and responses. I use it all the time.</p>



<h2><a class="rank-math-link" href="https://tableplus.com/" target="_blank" rel="noopener">TablePlus</a></h2>



<p>If you do any work with databases then you&#8217;ve got to give TablePlus a go. It&#8217;ll also connect to Redis too!</p>



<h2><a class="rank-math-link" href="https://www.getcloudapp.com/" target="_blank" rel="noopener">CloudApp</a></h2>



<p>Great tool for taking and sharing screen shots and screen recordings. I use this all the time to share things with people online.</p>



<h2><a class="rank-math-link" href="https://brew.sh/" target="_blank" rel="noopener">Homebrew</a></h2>



<p>The magic of everything! The Missing Package Manager for macOS (or Linux). If it can be installed using Brew then it should be installed using brew!</p>



<p>Things I then went on to install using Homebrew:</p>



<ol><li>brew install node</li><li><s>brew install redis</s> (actually don&#8217;t do this, see DBngin below)</li></ol>



<h2><a href="https://iterm2.com/" class="rank-math-link" target="_blank" rel="noopener">iTerm2</a></h2>



<p>If you spend a lot of your time in the terminal then iTerm2 will help add some helpful features to your day-to-day routines. </p>



<p>Once you have iTerm2 installed install <a href="https://github.com/ohmyzsh/ohmyzsh" class="rank-math-link" target="_blank" rel="noopener">ohmyzsh</a> and take advantage of the many <a href="https://github.com/ohmyzsh/ohmyzsh#plugins" class="rank-math-link" target="_blank" rel="noopener">plugins</a> and <a href="https://github.com/ohmyzsh/ohmyzsh#themes" class="rank-math-link" target="_blank" rel="noopener">themes</a> available to you.</p>



<h3>Install Git</h3>



<p>Install &#8220;Developer Tools&#8221;. This will happen once you type &#8220;git&#8221; into the terminal. for the first time (if not already installed).</p>



<h3>Create an SSH Key</h3>



<p>Loads of places to show you how to do this. If you&#8217;re setting up a new Mac you probably already have one you can just move. I&#8217;ve decided to create a new one. <a href="https://docs.gitlab.com/ee/ssh/README.html#generate-an-ssh-key-pair" class="rank-math-link" target="_blank" rel="noopener">GitLab has some help for you here</a>. </p>



<p>You can copy your key&#8217;s content by using <a class="rank-math-link" href="https://docs.gitlab.com/ee/ssh/README.html#add-an-ssh-key-to-your-gitlab-account" target="_blank" rel="noopener">this hand snippet</a>. </p>



<p>If you don&#8217;t want to type your passphrase each time then add the below to your config file ($ touch ~/.ssh/config) (<a class="rank-math-link" href="https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent#adding-your-ssh-key-to-the-ssh-agent" target="_blank" rel="noopener">More info here</a>)</p>



<pre class="wp-block-code"><code>Host *
  UseKeychain yes</code></pre>



<h2>Local Development (Laravel Focused)</h2>



<ul><li><a href="https://getcomposer.org/" class="rank-math-link" target="_blank" rel="noopener">Composer</a></li><li><a href="https://laravel.com/docs/8.x/valet#installation" class="rank-math-link" target="_blank" rel="noopener">Laravel Valet</a></li></ul>



<h2><a class="rank-math-link" href="https://dbngin.com/" target="_blank" rel="noopener">DBngin</a></h2>



<blockquote class="wp-block-quote"><p>Free All-in-One Database Version Management Tool! The easiest way to get started with PostgreSQL, MySQL, Redis &amp; more</p><cite>DBngin.com</cite></blockquote>



<p>This is a game changer when it comes to getting a local database and Redis running locally to use with Valet. By the same awesome people as TablePlus.</p>



<h2><a href="https://tinkerwell.app/" class="rank-math-link" target="_blank" rel="noopener">TinkerWell</a></h2>



<p>I&#8217;ve only just started to use this but it seems helpful.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2021/06/21/applications-to-install-on-a-new-macbook-pro/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1291</post-id>	</item>
		<item>
		<title>Showing if a user is online in Laravel</title>
		<link>https://jamesmills.co.uk/2020/06/07/showing-if-a-user-is-online-in-laravel/</link>
					<comments>https://jamesmills.co.uk/2020/06/07/showing-if-a-user-is-online-in-laravel/#comments</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Sun, 07 Jun 2020 13:25:45 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[online]]></category>
		<category><![CDATA[user]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1244</guid>

					<description><![CDATA[I&#8217;m working on a little project for work which will allow all our team to log in using our Google Mail accounts. I was able to get the auth set up quickly with Laravel Socialite and added a quick restriction to make sure that only people with an @clicksco.com email address was able to log [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;m working on a little project for work which will allow all our team to log in using our Google Mail accounts. I was able to get the auth set up quickly with Laravel Socialite and added a quick restriction to make sure that only people with an @clicksco.com email address was able to log in.</p>



<p>We are using the amazing <a href="https://tailwindui.com" class="rank-math-link" target="_blank" rel="noopener">Tailwind UI</a> framework for the project and I&#8217;m using the <em>Application UI &gt;Lists &gt; Wide Lists &gt; Two-column with avatar</em> list.</p>



<figure class="wp-block-image size-large"><img data-attachment-id="1245" data-permalink="https://jamesmills.co.uk/2020/06/07/showing-if-a-user-is-online-in-laravel/screenshot-2020-06-07-17-08-43/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?fit=2832%2C980&amp;ssl=1" data-orig-size="2832,980" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2020-06-07-17.08.43" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?fit=300%2C104&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?fit=640%2C221&amp;ssl=1" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?fit=640%2C221&amp;ssl=1" alt="" class="wp-image-1245" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?w=2832&amp;ssl=1 2832w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?resize=300%2C104&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?resize=1024%2C354&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?resize=768%2C266&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?resize=1536%2C532&amp;ssl=1 1536w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?resize=2048%2C709&amp;ssl=1 2048w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?w=1280&amp;ssl=1 1280w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.08.43.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure>



<p>I wanted to use a little online indicator to show if the user was online or not</p>



<figure class="wp-block-image size-large"><img data-attachment-id="1246" data-permalink="https://jamesmills.co.uk/2020/06/07/showing-if-a-user-is-online-in-laravel/screenshot-2020-06-07-17-11-16/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?fit=1138%2C362&amp;ssl=1" data-orig-size="1138,362" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2020-06-07-17.11.16" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?fit=300%2C95&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?fit=640%2C204&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?fit=640%2C204&amp;ssl=1" alt="" class="wp-image-1246" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?w=1138&amp;ssl=1 1138w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?resize=300%2C95&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?resize=1024%2C326&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/06/Screenshot-2020-06-07-17.11.16.png?resize=768%2C244&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" /></figure>



<p>I decided to create a <code>UserLastSeenAt</code> Middleware and add it to my web routes file which would store the datetime the user was last seen in the cache.</p>



<p>First create the Middleware which can do using <code>php artisan make:middleware UserLastSeenAt</code></p>



<pre class="wp-block-code"><code>&lt;?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Cache;

class UserLastSeenAt
{
    public function handle($request, Closure $next)
    {
        Cache::put('user-last-seen:' . auth()->user()->id, now());

        return $next($request);
    }
}</code></pre>



<p>Now register this new Middleware so you can use it in the route file</p>



<pre class="wp-block-code"><code>// App\Http\Kernel

use App\Http\Middleware\UserLastSeenAt;

protected $routeMiddleware = &#91;
    'auth' => \App\Http\Middleware\Authenticate::class,
    ...
    'user.last.seen' => UserLastSeenAt::class,
];</code></pre>



<p>Now you can use it in the web routes file like this</p>



<pre class="wp-block-code"><code>// web.php

Route::middleware('auth', 'user.last.seen')->group(function () {
    Route::get('/', 'HomeController@index')->name('home');
});</code></pre>



<p>I then created a little helper function on my <code>User</code> model.</p>



<pre class="wp-block-code"><code>public function isOnline()
{
    $lastSeen = Cache::get('user-last-seen:' . $this->id, null);

    if (!is_null($lastSeen) &amp;&amp; $lastSeen->diffInMinutes(now()) &lt; 2) {
        return true;
    }

    return false;
}</code></pre>



<p>And now in the blade view file I can just do this</p>



<pre class="wp-block-code"><code>&lt;div class="flex-shrink-0">
    &lt;span class="inline-block relative">
        &lt;img class="h-12 w-12 rounded-full" src="{{ $user->avatar }}" />
        @if($user->isOnline())
            &lt;span class="absolute top-0 right-0 block h-2.5 w-2.5 rounded-full text-white shadow-solid bg-green-400">&lt;/span>
        @endif
    &lt;/span>
&lt;/div></code></pre>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2020/06/07/showing-if-a-user-is-online-in-laravel/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1244</post-id>	</item>
		<item>
		<title>The tools and services I use</title>
		<link>https://jamesmills.co.uk/2019/12/10/the-tools-and-services-i-use/</link>
					<comments>https://jamesmills.co.uk/2019/12/10/the-tools-and-services-i-use/#comments</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Tue, 10 Dec 2019 07:34:41 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[uses]]></category>
		<category><![CDATA[workflow]]></category>
		<category><![CDATA[workstation]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1158</guid>

					<description><![CDATA[Workstation MacBook Pro (13-inch, 2018) I made the switch to use a 13&#8243; MacBook last year. I have used a 15&#8243; MacBook for most of my career but I made the switch for portability. It&#8217;s powerful enough (just) for what I use. I wish I could have gone for the 32GB of RAM but the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2>Workstation</h2>



<div class="wp-block-image"><figure class="aligncenter size-large"><img data-attachment-id="1183" data-permalink="https://jamesmills.co.uk/2019/12/10/the-tools-and-services-i-use/img_1011/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?fit=2560%2C1920&amp;ssl=1" data-orig-size="2560,1920" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;1.8&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;iPhone X&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;1578213866&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;4&quot;,&quot;iso&quot;:&quot;50&quot;,&quot;shutter_speed&quot;:&quot;0.058823529411765&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="IMG_1011" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?fit=300%2C225&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?fit=640%2C480&amp;ssl=1" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011.jpg?resize=640%2C480&#038;ssl=1" alt="" class="wp-image-1183" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?resize=1024%2C768&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?resize=300%2C225&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?resize=768%2C576&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?resize=1536%2C1152&amp;ssl=1 1536w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?resize=2048%2C1536&amp;ssl=1 2048w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?w=1280&amp;ssl=1 1280w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/IMG_1011-scaled.jpg?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /><figcaption>Workstation December 2019</figcaption></figure></div>



<p><strong>MacBook Pro (13-inch, 2018)</strong></p>



<p>I made the switch to use a 13&#8243; MacBook last year. I have used a 15&#8243; MacBook for most of my career but I made the switch for portability. It&#8217;s powerful enough (just) for what I use. I wish I could have gone for the 32GB of RAM but the 16GB just about gets me by.</p>



<p><strong>Apple Magic Mouse &amp; Apple Keyboard</strong></p>



<p>Anything that means I don&#8217;t have to have cables anywhere keeps me happy. Having an external mouse and keyword just makes sense to me.</p>



<p><strong>Samsung Monitor</strong></p>



<p>When I decided to go with the 13&#8243; MacBook I also committed to getting a good sized monitor so that I could dock my MacBook. For the majority of my career, I have been a huge advocate of using two monitors. This was a big decision but having one screen seems to keep me more focused. </p>



<p>I got some little box&#8217;s from <a href="https://www.muji.com/" target="_blank" rel="noopener">Muji</a> which I use as a monitor stand. I prefer to keep my monitor high to try and help aid my sitting position so that I am looking up or directly ahead at my screen. One day when I am rich and famous I will invest in everything from <a href="https://grovemade.com/" target="_blank" rel="noopener">grovemade.com</a></p>



<p><strong>Plants</strong></p>



<p>I like to be surrounded by plants. I am not sure why but I feel they help my mental health. I feel they bring an element of calm when working in an open office.</p>



<h2>Development</h2>



<p><a href="https://www.jetbrains.com/phpstorm/" target="_blank" rel="noopener"><strong>PHPStorm</strong></a></p>



<p>I have tried them all. I started my career using Dreamweaver, progresses to Sublime and then found PHPStorm. I absolutely love PHPSotm. I prefer to keep the minimalistic look and feel so I have a lot of things hidden.</p>



<p><a href="https://www.sequelpro.com/" target="_blank" rel="noopener"><strong>Sequel Pro</strong></a></p>



<p>I have been using Sequel Pro for a long time. Although I am getting very frustrated with the bug that exits the app when I close a tab, I am still to move over to <a href="https://tableplus.com/" target="_blank" rel="noopener">Table Plus</a>. I have it installed, I just always find myself reaching for Sequel Pro.</p>



<p><a href="https://iterm2.com/" target="_blank" rel="noopener"><strong>iTerm 2</strong></a></p>



<p>I use iTerm with <a href="https://github.com/robbyrussell/oh-my-zsh" target="_blank" rel="noopener">oh-my-zsh</a> plugin. Using zsh allows you to install plugins like <a href="https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md" target="_blank" rel="noopener">Auto Suggestions</a> which helps.</p>



<p><a href="https://brew.sh/" target="_blank" rel="noopener"><strong>Homebrew</strong></a></p>



<p>Quoting Jeffrey Way &#8220;If it can be installed through Homebrew, then I’m installing it through Homebrew. And that’s all I have to say about that.&#8221;. I agree.</p>



<p><strong><a href="https://www.git-tower.com/" target="_blank" rel="noopener">GitTower</a></strong></p>



<p>I know it&#8217;s highly debated if you should use a GUI for Git or use the command-line.  I should probably know more about Git&#8217;s command-line commands but, that&#8217;s life. I use GitTower and absolutely love it. We use GitFlow to ease our workflow and things work well.</p>



<p><strong><a href="http://getmedis.com/" target="_blank" rel="noopener">Medis</a></strong></p>



<p>We use Redis quite a lot and having a tool to be able to manage and view Redis comes in handy.</p>



<p><strong><a href="https://www.getpostman.com/" target="_blank" rel="noopener">Postman</a></strong></p>



<p>For API development and API testing Postman is something I use a lot.</p>



<h2>Workflow</h2>



<p><a href="https://clubhouse.io/" target="_blank" rel="noopener"><strong>Clubhouse</strong></a></p>



<p>One of the newest tools in my toolbox. I have tried a number of tools for project management including Trello and Codebase. Codebase was a huge part of the last four years as mentioned in my article about <a href="https://jamesmills.co.uk/2014/06/26/clicksco-php-flow/">Clicksco PHP Flow in 2014</a> however it felt clunky. I stumbled across Clubhouse and after an initial trial, I switch my team over to it and haven&#8217;t looked back since. It has seamless integrations with a number of services.</p>



<p><a href="https://evernote.com/" target="_blank" rel="noopener"><strong>Evernote</strong></a></p>



<p>This may sound like an odd one given there are a million other tools out there which probably do a better job. However, I have been using Evernote for years now and it has a huge history of notes, brain dumps and lists. </p>



<p>Everything goes into Evernote, everything! I have install guides, technical note and diagrams, brain dumps, to-do lists. Everything! It just works for me. Once it&#8217;s out of my brain I can concentration getting things done rather than going over and over in my head what I need to remember.</p>



<p><a href="https://sparkmailapp.com/" target="_blank" rel="noopener"><strong>Spark Mail</strong></a></p>



<p>This one is relatively new to me. I found out about it from someone on Twitter. I tried it and in less than a day I had moved to use it permanently for Mobile and Desktop. I use Google Mail to power my mail (work and personally) and it&#8217;s almost enjoyable to work with email again.</p>



<p><a href="https://1password.com/" target="_blank" rel="noopener"><strong>1Password</strong></a></p>



<p>I don&#8217;t use the browser password managers. I have used 1Password for a long time now. It helps me sleep at night. The browser plugins are amazing. If you don&#8217;t use a password manager then please start to use one today!</p>



<h2>Services</h2>



<p><a href="https://forge.laravel.com" target="_blank" rel="noopener"><strong>Laravel Forge</strong></a></p>



<p>I have been using Laravel Forge for years. It&#8217;s an amazing tool to spin up new servers in seconds.</p>



<p><a href="https://envoyer.io" target="_blank" rel="noopener"><strong>Laravel Envoyer</strong></a></p>



<p>Simple zero-downtime deployments. This tool gives me the control I need when deploying a multitude of different projects f different sizes and complexities.</p>



<p><a href="https://laravelshift.com" target="_blank" rel="noopener"><strong>Laravel Shift</strong></a></p>



<p>I use Laravel Shift on a number of projects. I use the Shift service and also the Fixer. I also use the automated dependency updater as part of our CI process.</p>



<p><strong><a href="https://sentry.io" target="_blank" rel="noopener">Sentry.io</a></strong></p>



<p>I have been using Sentry for a long time now for exception tracking in my production apps. I love how it </p>



<h2>Other Stuff</h2>



<p><strong><a href="https://www.spotify.com/" target="_blank" rel="noopener">Spotify</a> &amp; <a href="https://soundcloud.com/jamesgmills" target="_blank" rel="noopener">Soundcloud</a></strong></p>



<p>I really wouldn&#8217;t be able to work without my paid <a href="https://www.spotify.com/" target="_blank" rel="noopener">Spotify</a> account. I also listen to <a href="https://soundcloud.com/jamesgmills" target="_blank" rel="noopener">Soundcloud</a>. I like a mix of music. I am usually listening to some Hip Hop or if I am focusing I tend to listen to <a href="https://soundcloud.com/twofriendsfriendlysessions" target="_blank" rel="noopener">2F Friendly Sessions</a> or <a href="https://soundcloud.com/trademarkbootlegs/sets/the-pregame-series" target="_blank" rel="noopener">Trademarks The Pregame Series</a></p>



<p><a href="https://www.techradar.com/reviews/audio-visual/hi-fi-and-audio/headphones/bose-quietcomfort-35-1322715/review" target="_blank" rel="noopener"><strong>Bose Noise Cancelling Headphones</strong></a></p>



<p>I remember the first day I invested in some Bose Nise Cancelling Headphones. My productivity and mental health shot through the roof! I cannot recommend a good set of headphones enough for anyone who spends part of their day in &#8220;focus time&#8221;. I currently have some Bose QuietComfort 35 wireless headphones.</p>



<h2>Awesome Uses</h2>



<p>I am not sure where the Awesome Uses started but Wes Bos has a list of loads of people who have added a /uses page to their website here <a href="https://github.com/wesbos/awesome-uses" target="_blank" rel="noopener">https://github.com/wesbos/awesome-uses</a> a few of my favourite are listed below.</p>



<ul><li><a href="https://twitter.com/jeffrey_way" target="_blank" rel="noopener">Jeffrey Way</a> &#8211; <a href="https://laracasts.com/uses" target="_blank" rel="noopener">laracasts.com/uses</a></li><li><a href="https://twitter.com/ericlbarnes" target="_blank" rel="noopener">Eric Barnes</a> &#8211; <a href="https://ericlbarnes.com/uses/" target="_blank" rel="noopener">ericlbarnes.com/uses</a></li><li><a href="https://twitter.com/adamwathan" target="_blank" rel="noopener">Adam Wathan</a> &#8211; <a href="https://adamwathan.me/uses/" target="_blank" rel="noopener">adamwathan.me/uses</a></li></ul>



<p>Photo by&nbsp;<a href="https://unsplash.com/@austindistel?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" target="_blank" rel="noopener">Austin Distel</a>&nbsp;on&nbsp;<a href="https://unsplash.com/?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" target="_blank" rel="noopener">Unsplash</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/12/10/the-tools-and-services-i-use/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1158</post-id>	</item>
		<item>
		<title>My packages are now Treeware</title>
		<link>https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/</link>
					<comments>https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Mon, 02 Dec 2019 16:30:29 +0000</pubDate>
				<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[earth]]></category>
		<category><![CDATA[forest]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[packagest]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1130</guid>

					<description><![CDATA[UPDATE: 9th January 2020I&#8217;m really pleased to say that other people are starting to add #Treeware to their packages. I have started to curate a list here. When Freek published &#8220;Our packages are now postcardware&#8221; I was intrigued to know what Postcardware was. Postcardware, also called just cardware, is a style of software distribution similar [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><strong>UPDATE: 9th January 2020<br></strong>I&#8217;m really pleased to say that other people are starting to add <a href="https://twitter.com/search?q=%23Treeware&amp;src=typed_query" target="_blank" rel="noopener">#Treeware</a> to their packages. <a href="https://jamesmills.co.uk/treeware">I have started to curate a list here</a>.</p>



<hr class="wp-block-separator"/>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>When Freek published &#8220;<a href="https://freek.dev/531-our-packages-are-now-postcardware " target="_blank" rel="noopener">Our packages are now postcardware</a>&#8221; I was intrigued to know what <a href="https://en.wikipedia.org/wiki/Postcardware" target="_blank" rel="noopener">Postcardware</a> was.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<blockquote class="wp-block-quote is-style-large"><p><strong>Postcardware</strong>, also called just <strong>cardware</strong>, is a style of software distribution similar to <a href="https://en.wikipedia.org/wiki/Shareware" target="_blank" rel="noopener">shareware</a>, distributed by the author on the condition that users send the author a <a href="https://en.wikipedia.org/wiki/Postcard" target="_blank" rel="noopener">postcard</a>. </p><cite>https://en.wikipedia.org/wiki/Postcardware</cite></blockquote>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<p>We use a number of <a href="https://spatie.be/open-source/packages" target="_blank" rel="noopener">Spatie packages</a> and so I was determined to do my bit and &#8220;send the author a postcard&#8221;. You will notice that on all of Spatie packages in the README.md file there is a licence.</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1136" data-permalink="https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/screenshot-2019-12-02-20-23-40/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?fit=1844%2C424&amp;ssl=1" data-orig-size="1844,424" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-12-02-20.23.40" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?fit=300%2C69&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?fit=640%2C147&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?fit=640%2C147&amp;ssl=1" alt="" class="wp-image-1136" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?w=1844&amp;ssl=1 1844w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?resize=300%2C69&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?resize=768%2C177&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?resize=1024%2C235&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.23.40.png?w=1280&amp;ssl=1 1280w" sizes="(max-width: 640px) 100vw, 640px" /></figure></div>



<p>I live in Dubai and it&#8217;s tricky to send international post so I hand-delivered my postcard to Freek at Laracon and I was pleased to see it on <a href="https://spatie.be/open-source/postcards" target="_blank" rel="noopener">their website</a> soon after.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1131" data-permalink="https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/screenshot-2019-12-02-19-45-41/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?fit=2276%2C1190&amp;ssl=1" data-orig-size="2276,1190" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-12-02-19.45.41" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?fit=300%2C157&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?fit=640%2C334&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?fit=640%2C334&amp;ssl=1" alt="" class="wp-image-1131" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?w=2276&amp;ssl=1 2276w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?resize=300%2C157&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?resize=768%2C402&amp;ssl=1 768w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?resize=1024%2C535&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?w=1280&amp;ssl=1 1280w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-19.45.41.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h2>OK, so what&#8217;s Treeware</h2>



<p>Before I start to explain what Treeware is I need to touch on one more thing. I have known <a href="https://philsturgeon.uk" target="_blank" rel="noopener">Phil Sturgeon</a> for a long time and he has been a source of much inspiration. Phil is currently on a bike somewhere and in between biking and working he likes to shout about how we can do our bit to look after this beautiful planet we live on. </p>



<p>He has worked on a website called <a href="https://awesom.earth" target="_blank" rel="noopener">awesom.earth</a> and one of the services he has been supporting is <a href="https://offset.earth/?r=5ddfb08095bacf0018629749" target="_blank" rel="noopener">Offset Earth</a>. </p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<blockquote class="wp-block-quote is-style-large"><p>We plant trees &amp; fund the world’s best climate crisis solutions.</p><cite>Offset Earth</cite></blockquote>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>I have seen a big uplift in people adding methods of accepting payments to their opensource packages. GitHub and others have recently released various methods to help maintainers do this. I get it and I think there is a place for this but it didn&#8217;t sit well for me and for the small packages I have released. I loved the idea of Postcardware but it still didn&#8217;t feel right for me. When Phil shared with me his img.shields.io badge for &#8220;buy me a tree&#8221; I knew this was exactly the right fit for me.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1132" data-permalink="https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/screenshot-2019-12-02-20-05-32/" data-orig-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.05.32.png?fit=222%2C50&amp;ssl=1" data-orig-size="222,50" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-12-02-20.05.32" data-image-description="" data-medium-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.05.32.png?fit=222%2C50&amp;ssl=1" data-large-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.05.32.png?fit=222%2C50&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-02-20.05.32.png?w=640&#038;ssl=1" alt="" class="wp-image-1132" data-recalc-dims="1"/><figcaption>https://img.shields.io/badge/Buy%20me%20a%20tree-%F0%9F%8C%B3-lightgreen</figcaption></figure></div>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p>I have now added the badge to all my packages</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1153" data-permalink="https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/screenshot-2019-12-03-15-06-30/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?fit=1988%2C652&amp;ssl=1" data-orig-size="1988,652" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-12-03-15.06.30" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?fit=300%2C98&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?fit=640%2C210&amp;ssl=1" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?fit=640%2C210&amp;ssl=1" alt="" class="wp-image-1153" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?w=1988&amp;ssl=1 1988w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?resize=300%2C98&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?resize=768%2C252&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?resize=1024%2C336&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?w=1280&amp;ssl=1 1280w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/12/Screenshot-2019-12-03-15.06.30.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure></div>



<p>As well as adding the simple badge with a link to my <a href="https://offset.earth/jamesmills" target="_blank" rel="noopener">offset.earth profile</a> I am also going to add a new section called &#8220;Treeware&#8221; and taking some inspiration from Spatie&#8217;s Postcardware text I am going to add the below to <a href="https://packagist.org/?query=jamesmills" target="_blank" rel="noopener">all my packages</a>.</p>


<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist99826410" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-treeware-md" class="file my-2">
      <div id="file-treeware-md-readme" class="Box-body readme blob tmp-p-5 tmp-p-xl-6 "
    style="overflow: auto" tabindex="0" role="region"
    aria-label="Treeware.md content, created by jamesmills on 10:35AM on December 03, 2019."
  >
    <article class="markdown-body entry-content container-lg" itemprop="text"><div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Treeware Option One</h2><a id="user-content-treeware-option-one" class="anchor" aria-label="Permalink: Treeware Option One" href="#treeware-option-one"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">This package is <a href="https://treeware.earth" rel="nofollow noopener" target="_blank">Treeware</a>. If you use it in production, then we ask that you <a href="https://plant.treeware.earth/%7Bvenfor%7D/%7Bpackage%7D" rel="nofollow noopener" target="_blank"><strong>buy the world a tree</strong></a> to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.</p>
<div class="markdown-heading" dir="auto"><h2 class="heading-element" dir="auto">Treeware Option Two</h2><a id="user-content-treeware-option-two" class="anchor" aria-label="Permalink: Treeware Option Two" href="#treeware-option-two"><svg class="octicon octicon-link" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg></a></div>
<p dir="auto">You're free to use this package, but if it makes it to your production environment you are required to buy the world a tree.</p>
<p dir="auto">It’s now common knowledge that one of the best tools to tackle the climate crisis and keep our temperatures from rising above 1.5C is to <a href="https://www.bbc.co.uk/news/science-environment-48870920" rel="nofollow noopener" target="_blank">plant trees</a>. If you support this package and contribute to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.</p>
<p dir="auto">You can buy trees here <a href="https://plant.treeware.earth/%7Bvendor%7D/%7Bpackage%7D" rel="nofollow noopener" target="_blank">offset.earth/treeware</a></p>
<p dir="auto">Read more about Treeware at <a href="http://treeware.earth" rel="nofollow noopener" target="_blank">treeware.earth</a></p>
</article>
  </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/jamesmills/add9a716c17628494e58f684b2615c66/raw/7de33a3e2bf0939321080c028ca4afe45492103f/Treeware.md" style="float:right" class="Link--inTextBlock" target="_blank" rel="noopener">view raw</a>
        <a href="https://gist.github.com/jamesmills/add9a716c17628494e58f684b2615c66#file-treeware-md" class="Link--inTextBlock" target="_blank" rel="noopener">
          Treeware.md
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com" target="_blank" rel="noopener">GitHub</a>
      </div>
    </div>
</div>




<p>I would love to hear your feedback on this initiative and would love to see if anyone else likes the idea enough to follow!</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator"/>



<p><a href="https://packagist.org/?query=jamesmills" target="_blank" rel="noopener">You can find all my available packages listed here on Packagist</a></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/12/02/my-packages-are-now-treeware/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1130</post-id>	</item>
		<item>
		<title>Laravel &#038; DataDog Timeseries Metric data using their API via TCP</title>
		<link>https://jamesmills.co.uk/2019/11/28/laravel-datadog-timeseries-metric-data-using-their-api-via-tcp/</link>
					<comments>https://jamesmills.co.uk/2019/11/28/laravel-datadog-timeseries-metric-data-using-their-api-via-tcp/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Thu, 28 Nov 2019 06:24:33 +0000</pubDate>
				<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[datadog]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[tcp]]></category>
		<category><![CDATA[timeseries]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1111</guid>

					<description><![CDATA[We recently started to trial some of the DataDog services for a recent project I have been working on. One of the things that jumped out at me was the ability to use one account for many services. Monitoring, uptime, API testing, application profiling, live dashboards&#8230;. the list goes on. The setup is simple, you [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>We recently started to trial some of the DataDog services for a recent project I have been working on. One of the things that jumped out at me was the ability to use one account for many services. Monitoring, uptime, API testing, application profiling, live dashboards&#8230;. the list goes on. </p>



<p>The setup is simple, you just install their Agent on your server and you are done. One problem for us is that all our servers are managed by our infrastructure management team and they build all our servers using FreeBSD&#8230; and there isn&#8217;t a FreeBSD compatible DataDog Agent.</p>



<h2>What if you cannot install the DataDog Agent?</h2>



<p></p>



<p>My initial reaction was to stop the payments and quit the trial. I would come back to DataDog in the future if the opportunity ever materialised. But then I saw they had an API.</p>



<p>One of the main things I wanted to do was start to log things from our application as and when they happen so I could monitor them on a live graph and set alerts for times when it looked like something was wrong. DataDog has Metrics for this and they work really nicely.</p>



<p>I had a quick Google around and searched Packagist but there wasn&#8217;t anything out there which did what I needed so I built <a href="https://github.com/jamesmills/laravel-datadog" target="_blank" rel="noopener">jamesmills/laravel-datadog</a>. </p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<blockquote class="wp-block-quote is-style-large"><p>A simple package for Laravel to wrap DataDog&#8217;s API for Timeseries metrics making sure the jobs are queued.</p><cite>jamesmills/laravel-datadog</cite></blockquote>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p>One of the main things which the DataDog Agent does is use StatsD to collect data and then submit it over UDP protocol. This is none-blocking and is obviously a much better way of doing things than hitting an API over TCP and waiting for a reply when you are simply logging a metric. </p>



<h2>Queue Everything</h2>



<p>Building a new package for Laravel meant that I would be able to utilise the queue so I could put the sending of the metric into a Job and then queue it and wrap all this behind a hand Facade.</p>



<h2>Tag Everything</h2>



<p>I recently added tagging to the package too. DataDog&#8217;s system allows you to do a lot of things so being able to tag things is a real help. In our application, we are using it&#8217;s multi-domain (multi-tenant), so it&#8217;s helpful for me to be able to add a tag for each domain.</p>



<h2>Other Packages</h2>



<p>I also found this package <a href="http://%20https//github.com/chaseconey/laravel-datadog-helper" target="_blank">chaseconey/laravel-datadog-helper</a>. If you are able to install the DataDog Agent and you are using Laravel I would strongly recommend you take a look at this package. It ads middleware so you can log response times of various things in your application. I really like this.</p>



<p>It&#8217;s worthing pointing out that DataDog have their own PHP package (<a href="https://github.com/DataDog/php-datadogstatsd" target="_blank" rel="noopener">DataDog/php-datadogstatsd</a>)  which you can install and use without the Agent. Unfortunately, this is still no good for our situation.</p>



<h2>What&#8217;s Next?</h2>



<p>I am not 100% convinced that I am using the Metric collection properly. With the Agent using StatsD it collecting data and then sending the data to DataDog after a set period. For example, it will collect everything locally using StatsD and then every 10 seconds it will send the data. This means that DataDog is expecting data every 10 seconds. When using the API method I have set up in the package I don&#8217;t do this I send a metric in real-time to their API. What this means is I end up with a very odd graph which looks like there is a constant &#8220;hit&#8221;</p>



<figure class="wp-block-image"><img data-attachment-id="1112" data-permalink="https://jamesmills.co.uk/2019/11/28/laravel-datadog-timeseries-metric-data-using-their-api-via-tcp/screenshot-2019-11-28-09-39-11/" data-orig-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?fit=2086%2C248&amp;ssl=1" data-orig-size="2086,248" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-11-28-09.39.11" data-image-description="" data-medium-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?fit=300%2C36&amp;ssl=1" data-large-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?fit=640%2C76&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?fit=640%2C76&amp;ssl=1" alt="" class="wp-image-1112" srcset="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?w=2086&amp;ssl=1 2086w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?resize=300%2C36&amp;ssl=1 300w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?resize=768%2C91&amp;ssl=1 768w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?resize=1024%2C122&amp;ssl=1 1024w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?w=1280&amp;ssl=1 1280w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.39.11.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure>



<p>I met with a couple of guys from the DataDog team here in Dubai this week and discussed this issue with them so I hope I will be able to update this article soon with what&#8217;s happening and maybe &#8220;fix&#8221; the package.</p>



<h2>Demand for the package</h2>



<p>What has surprised me was how many downloads the package has had. I wrote this package to help us with something I thought was going to be quite unique. However, with over 300 installs in a month of it&#8217;s release, it looks like others might be finding themselves in a similar situation?</p>



<figure class="wp-block-image"><img data-attachment-id="1113" data-permalink="https://jamesmills.co.uk/2019/11/28/laravel-datadog-timeseries-metric-data-using-their-api-via-tcp/screenshot-2019-11-28-09-57-29/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?fit=2294%2C1210&amp;ssl=1" data-orig-size="2294,1210" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-11-28-09.57.29" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?fit=300%2C158&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?fit=640%2C338&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?fit=640%2C338&amp;ssl=1" alt="" class="wp-image-1113" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?w=2294&amp;ssl=1 2294w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?resize=300%2C158&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?resize=768%2C405&amp;ssl=1 768w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?resize=1024%2C540&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?w=1280&amp;ssl=1 1280w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/11/Screenshot-2019-11-28-09.57.29.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/11/28/laravel-datadog-timeseries-metric-data-using-their-api-via-tcp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1111</post-id>	</item>
		<item>
		<title>Laravel Dubai</title>
		<link>https://jamesmills.co.uk/2019/07/30/laravel-dubai/</link>
					<comments>https://jamesmills.co.uk/2019/07/30/laravel-dubai/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Tue, 30 Jul 2019 10:41:09 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Dubai]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[dubai]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[meetup]]></category>
		<category><![CDATA[slack]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1085</guid>

					<description><![CDATA[Attending this years Laracon conference in New York City has renewed my energy to start a Laravel meetup in Dubai. I hope this is the start of something big for the Laravel community in Dubai and UAE. Sponsorship If you have any interest in sponsoring or supporting the Laravel Dubai community please get in touch, [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Attending this years Laracon conference in New York City has renewed my energy to start a Laravel meetup in Dubai. I hope this is the start of something big for the Laravel community in Dubai and UAE.</p>



<hr class="wp-block-separator"/>



<h2>Sponsorship</h2>



<p>If you have any interest in sponsoring or supporting the Laravel Dubai community please get in touch, I would love to discuss opportunities with you.</p>



<hr class="wp-block-separator"/>



<h2>Laravel Dubai Slack</h2>



<p>To get started I have created a Laravel Dubai Slack account which you can join by using this link <a href="https://join.slack.com/t/laraveldubai/shared_invite/enQtMjIzODU5OTE3NTU4LWE0NTQ4ZWMzOTFkMDY4YmM5OWJmZTcyOGYzZDc2N2JiZmI2NjI3OTFkOGNmZWMwZjJlM2ExM2M3OTI2ODg5Nzg" target="_blank" rel="noopener"><a href="https://join.slack.com/t/laraveldubai" target="_blank" rel="noopener"></a>https://join.slack.com/t/laraveldubai</a>. If you are in Dubai and work with Laravel then please join and say hello.</p>



<div class="wp-block-image"><figure class="aligncenter"><a href="https://join.slack.com/t/laraveldubai/shared_invite/enQtMjIzODU5OTE3NTU4LWE0NTQ4ZWMzOTFkMDY4YmM5OWJmZTcyOGYzZDc2N2JiZmI2NjI3OTFkOGNmZWMwZjJlM2ExM2M3OTI2ODg5Nzg" target="_blank" rel="noreferrer noopener"><img data-attachment-id="1086" data-permalink="https://jamesmills.co.uk/2019/07/30/laravel-dubai/slack/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/07/slack.png?fit=458%2C141&amp;ssl=1" data-orig-size="458,141" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="slack" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/07/slack.png?fit=300%2C92&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/07/slack.png?fit=458%2C141&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/07/slack.png?w=640&#038;ssl=1" alt="" class="wp-image-1086" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/07/slack.png?w=458&amp;ssl=1 458w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/07/slack.png?resize=300%2C92&amp;ssl=1 300w" sizes="(max-width: 458px) 100vw, 458px" data-recalc-dims="1" /></a></figure></div>



<hr class="wp-block-separator"/>



<h2>Laravel Dubai Meet-up</h2>



<p>More information about this to come&#8230; stay tuned&#8230; join the slack channel for instant updated.</p>



<hr class="wp-block-separator"/>



<h2>Laravel Dubai Website</h2>



<p>I have registered laraveldubai.com and hope to get something live soon.</p>



<hr class="wp-block-separator"/>



<h2>Laravel Dubai Twitter</h2>



<p>Someone has already registered @laraveldubai username so I am trying to get in touch with whoever that person is to try and get everything aligned. If this is you, please get in touch <img src="https://s.w.org/images/core/emoji/12.0.0-1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/07/30/laravel-dubai/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1085</post-id>	</item>
		<item>
		<title>Adding a helper file in Laravel</title>
		<link>https://jamesmills.co.uk/2019/06/11/adding-a-helpers-file-in-laravel/</link>
					<comments>https://jamesmills.co.uk/2019/06/11/adding-a-helpers-file-in-laravel/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Tue, 11 Jun 2019 04:36:58 +0000</pubDate>
				<category><![CDATA[Laravel]]></category>
		<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[functions]]></category>
		<category><![CDATA[helpers]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[tops]]></category>
		<category><![CDATA[tricks]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1054</guid>

					<description><![CDATA[Every now and then you will probably find yourself in the need to use a custom function in your Laravel application. I cannot think of one project which I have worked on where I haven&#8217;t needed to add a quick and easy custom function. Our controllers don&#8217;t contain actions outside of the 7 resource actions [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Every now and then you will probably find yourself in the need to use a custom function in your Laravel application. I cannot think of one project which I have worked on where I haven&#8217;t needed to add a quick and easy custom function. </p>



<p>Our controllers don&#8217;t contain actions outside of the 7 resource actions (<code>index</code>, <code>create</code>, <code>store</code>, <code>show</code>, <code>edit</code>, <code>update</code>, <code>destroy</code>). For more details on this principle, review <a rel="noreferrer noopener" href="https://laravel.com/docs/5.7/controllers#resource-controllers" target="_blank">the docs</a> or watch <a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=MF0jFKvS4SI" target="_blank">Cruddy by Design</a></p>



<p>So, what happens if you need a custom function here? You could refactor this out into its own class in a Helpers namespace, I have done this before too. However, sometimes you just want to use a function.</p>



<h2>Example use case</h2>



<p>One example we have is where we run a number of subdomains off our main application. We have <code>app</code>, <code>api</code>, <code>admin</code> and <code>search</code>. We store the root URL in the <code>.env</code> file as <code>APP_URL=https://intentmatch.dev</code> and then we have a helper function which we use to get the URL throughout our application.</p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist96667435" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-helperfunctions-php" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-php  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="HelperFunctions.php content, created by jamesmills on 04:29AM on June 11, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank" rel="noopener">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="HelperFunctions.php">
        <tr>
          <td id="file-helperfunctions-php-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-helperfunctions-php-LC1" class="blob-code blob-code-inner js-file-line">&lt;?php</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-helperfunctions-php-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-helperfunctions-php-LC3" class="blob-code blob-code-inner js-file-line">if (!function_exists(&#39;applicationUrl&#39;)) {</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-helperfunctions-php-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-helperfunctions-php-LC5" class="blob-code blob-code-inner js-file-line">    /**</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-helperfunctions-php-LC6" class="blob-code blob-code-inner js-file-line">     * Will return the fully qualified domain name for the correct environment etc</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-helperfunctions-php-LC7" class="blob-code blob-code-inner js-file-line">     *</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-helperfunctions-php-LC8" class="blob-code blob-code-inner js-file-line">     * @param string $sub_domain</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-helperfunctions-php-LC9" class="blob-code blob-code-inner js-file-line">     * @param string $path</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-helperfunctions-php-LC10" class="blob-code blob-code-inner js-file-line">     * @return string</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-helperfunctions-php-LC11" class="blob-code blob-code-inner js-file-line">     */</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-helperfunctions-php-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-helperfunctions-php-LC13" class="blob-code blob-code-inner js-file-line">    function applicationUrl($sub_domain = &#39;app&#39;, $path = null)</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-helperfunctions-php-LC14" class="blob-code blob-code-inner js-file-line">    {</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-helperfunctions-php-LC15" class="blob-code blob-code-inner js-file-line">        $related_link = parse_url(config(&#39;app.url&#39;));</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-helperfunctions-php-LC16" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-helperfunctions-php-LC17" class="blob-code blob-code-inner js-file-line">        $final_url = $related_link[&#39;scheme&#39;] . &#39;://&#39; . $sub_domain . &#39;.&#39; . $related_link[&#39;host&#39;];</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-helperfunctions-php-LC18" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-helperfunctions-php-LC19" class="blob-code blob-code-inner js-file-line">        if (!is_null($path)) {</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-helperfunctions-php-LC20" class="blob-code blob-code-inner js-file-line">            $final_url .= &#39;/&#39; . ltrim($path, &#39;/&#39;);</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-helperfunctions-php-LC21" class="blob-code blob-code-inner js-file-line">        }</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-helperfunctions-php-LC22" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-helperfunctions-php-LC23" class="blob-code blob-code-inner js-file-line">        return $final_url;</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-helperfunctions-php-LC24" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-helperfunctions-php-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-helperfunctions-php-LC25" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/jamesmills/33a07546e1ff5cbe838fe53d3f3c2190/raw/e2d4261c307a10953db12b735087acde17018bec/HelperFunctions.php" style="float:right" class="Link--inTextBlock" target="_blank" rel="noopener">view raw</a>
        <a href="https://gist.github.com/jamesmills/33a07546e1ff5cbe838fe53d3f3c2190#file-helperfunctions-php" class="Link--inTextBlock" target="_blank" rel="noopener">
          HelperFunctions.php
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com" target="_blank" rel="noopener">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>We keep functions like this in <code>App/Helpers/HelperFunctions.php</code> and we often have helper classes in this namespace too. The <code>HelperFunctions.php</code> file is dedicated to quick and easy functions.</p>



<h2>Include in Composer.json</h2>



<p>Your helper classes will load automatically because they are in the main Application namespace but you need to include the Helper file individually in your <code>composer.json</code> file so that it gets found. To do this just update your <code>composer.json</code> file and add the <code>files</code> round the autoload key.</p>



<pre class="wp-block-code"><code>"autoload": {
     "classmap": &#91;
         "database
     ],
     "psr-4": {
         "App\": "app/"
     },
     "files": &#91;
         "app/Helpers/HelperFunctions.php"
     ]
 }</code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/06/11/adding-a-helpers-file-in-laravel/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1054</post-id>	</item>
		<item>
		<title>How to set Social Sharing Images</title>
		<link>https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/</link>
					<comments>https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/#respond</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Thu, 06 Jun 2019 13:06:12 +0000</pubDate>
				<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[open graph]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[sharing]]></category>
		<category><![CDATA[social]]></category>
		<category><![CDATA[twitter]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=769</guid>

					<description><![CDATA[You may have noticed that when you share my blog posts on Social Media and services like Slack, Telegram and WhatsApp etc. you get to see a nice image accompanying the link to the post. Improved CTR These images really help with Click Through Rate (CTR) and I have found that engagement on the shares [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>You may have noticed that when you share my blog posts on Social Media and services like Slack, Telegram and WhatsApp etc. you get to see a nice image accompanying the link to the post.</p>



<div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="wp-block-image"><figure class="aligncenter is-resized"><img data-attachment-id="1036" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/screenshot-2019-06-06-11-06-53/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?fit=920%2C322&amp;ssl=1" data-orig-size="920,322" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-06-06-11.06.53" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?fit=300%2C105&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?fit=640%2C224&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?resize=460%2C161&#038;ssl=1" alt="" class="wp-image-1036" width="460" height="161" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?w=920&amp;ssl=1 920w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?resize=300%2C105&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.06.53.png?resize=768%2C269&amp;ssl=1 768w" sizes="(max-width: 460px) 100vw, 460px" data-recalc-dims="1" /></figure></div>



<div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="wp-block-jetpack-tiled-gallery aligncenter is-style-square"><div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="tiled-gallery__gallery"><div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="tiled-gallery__row columns-2"><div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="tiled-gallery__col"><figure class="tiled-gallery__item"><img data-attachment-id="1038" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/screenshot-2019-06-06-11-12-34/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?fit=1918%2C1290&amp;ssl=1" data-orig-size="1918,1290" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-06-06-11.12.34" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?fit=300%2C202&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?fit=640%2C431&amp;ssl=1" data-attachment-id="1038" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/screenshot-2019-06-06-11-12-34/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?fit=1918%2C1290&amp;ssl=1" data-orig-size="1918,1290" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-06-06-11.12.34" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?fit=300%2C202&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?fit=640%2C431&amp;ssl=1" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?resize=600%2C600&#038;strip=info&#038;ssl=1 600w,https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?resize=900%2C900&#038;strip=info&#038;ssl=1 900w,https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?resize=1200%2C1200&#038;strip=info&#038;ssl=1 1200w,https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?resize=1290%2C1290&#038;strip=info&#038;ssl=1 1290w" alt="" data-height="1290" data-id="1038" data-link="https://jamesmills.co.uk/?attachment_id=1038" data-url="https://jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png" data-width="1918" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.12.34.png?ssl=1&amp;resize=1290%2C1290"/></figure></div><div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="tiled-gallery__col"><figure class="tiled-gallery__item"><img data-attachment-id="1037" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/img_3036/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?fit=1125%2C2436&amp;ssl=1" data-orig-size="1125,2436" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="IMG_3036" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?fit=139%2C300&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?fit=473%2C1024&amp;ssl=1" data-attachment-id="1037" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/img_3036/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?fit=1125%2C2436&amp;ssl=1" data-orig-size="1125,2436" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="IMG_3036" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?fit=139%2C300&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?fit=473%2C1024&amp;ssl=1" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?resize=600%2C600&#038;strip=info&#038;ssl=1 600w,https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?resize=900%2C900&#038;strip=info&#038;ssl=1 900w,https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?resize=1125%2C1125&#038;strip=info&#038;ssl=1 1125w" alt="" data-height="2436" data-id="1037" data-link="https://jamesmills.co.uk/?attachment_id=1037" data-url="https://jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png" data-width="1125" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3036.png?ssl=1&amp;resize=1125%2C1125"/></figure></div></div></div></div>



<h2>Improved CTR</h2>



<p>These images really help with Click Through Rate (CTR) and I have found that engagement on the shares and posts are so much higher with more likes, retweets and comments when there is a featured image included.</p>



<h2>Manually code all the tags</h2>



<p>There are a number of ways to achieve this. You can code the Open Graph tags, Twitter Card tags etc into the head part of your page. There is an amazing list of these tags maintained by <a href="https://github.com/joshbuchea/HEAD" target="_blank" rel="noopener">Josh Buchea on GitHub</a>.</p>



<p>The main ones you want to consider:</p>



<ul><li><a href="https://github.com/joshbuchea/HEAD#facebook-open-graph" target="_blank" rel="noopener">Facebook Open Graph</a></li><li><a href="https://github.com/joshbuchea/HEAD#twitter-card" target="_blank" rel="noopener">Twitter Card</a></li><li><a href="https://github.com/joshbuchea/HEAD#schemaorg" target="_blank" rel="noopener">Schema.org</a></li></ul>



<p>Make sure you include the Open Graph ones. You can read more about the <a href="http://ogp.me/" target="_blank" rel="noopener">Open Graph protocol</a> here. I have found that most of the services like WhatsApp, LinkedIn, Facebook and Twitter will all fall back to use the Open Graph tags if you don&#8217;t use anything else. </p>



<p>I would still advise using the Twitter Card and trying to mark up your data with Scema.org markup if you can.</p>



<h2>Creating the image</h2>



<p>There is so much conflicting information on the web about what sizes the image should be for the various different tools and services.</p>



<p>One company who I have been following since they started is Buffer. They are an incredibly amazing company for so many reasons (I might touch on them in a future post). They have covered the image size topic here on their blog where they talk about <a href="http:// https://buffer.com/library/ideal-image-sizes-social-media-posts" target="_blank">ideal image sizes social media posts</a>.</p>



<div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1040" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/infographic-blog-01/" data-orig-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?fit=1500%2C600&amp;ssl=1" data-orig-size="1500,600" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="infographic-blog-01" data-image-description="" data-medium-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?fit=300%2C120&amp;ssl=1" data-large-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?fit=640%2C256&amp;ssl=1" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?fit=640%2C256&amp;ssl=1" alt="" class="wp-image-1040" srcset="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?w=1500&amp;ssl=1 1500w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?resize=300%2C120&amp;ssl=1 300w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?resize=768%2C307&amp;ssl=1 768w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?resize=1024%2C410&amp;ssl=1 1024w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/infographic-blog-01.png?w=1280&amp;ssl=1 1280w" sizes="(max-width: 640px) 100vw, 640px" /></figure></div>



<p>Buffer built an amazing service called <a href="https://pablo.buffer.com" target="_blank" rel="noopener">Pablo</a>. Pablo allows you to either pick an image from their gallery or upload your own. You can quickly and easily add titles and text on top of the image. You pick the font and the layout. Then, with one click, you can download the optimised version of the image.</p>



<div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1045" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/screenshot-2019-06-06-16-07-18/" data-orig-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?fit=2672%2C1760&amp;ssl=1" data-orig-size="2672,1760" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2019-06-06 16.07.18" data-image-description="" data-medium-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?fit=300%2C198&amp;ssl=1" data-large-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?fit=640%2C421&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?resize=640%2C421&#038;ssl=1" alt="" class="wp-image-1045" srcset="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?resize=1024%2C674&amp;ssl=1 1024w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?resize=300%2C198&amp;ssl=1 300w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?resize=768%2C506&amp;ssl=1 768w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?w=1280&amp;ssl=1 1280w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-16.07.18.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /><figcaption>Screen shot of the Pablo service by Buffer.</figcaption></figure></div>



<figure class="wp-block-gallery columns-3 is-cropped"><ul data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="blocks-gallery-grid"><li class="blocks-gallery-item"><figure><img data-attachment-id="1032" data-permalink="https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/pablo-7/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pablo (7)" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?fit=640%2C320&amp;ssl=1" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?resize=640%2C320&#038;ssl=1" alt="" data-id="1032" data-link="https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/pablo-7/" class="wp-image-1032" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?w=1024&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?resize=300%2C150&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/pablo-7.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li><li class="blocks-gallery-item"><figure><img data-attachment-id="1005" data-permalink="https://jamesmills.co.uk/2019/05/06/favourite-laravel-packages-i-always-install/pablo-5-2/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pablo (5)" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?fit=640%2C320&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?resize=640%2C320&#038;ssl=1" alt="" data-id="1005" data-link="https://jamesmills.co.uk/2019/05/06/favourite-laravel-packages-i-always-install/pablo-5-2/" class="wp-image-1005" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?w=1024&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?resize=300%2C150&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/05/pablo-5.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li><li class="blocks-gallery-item"><figure><img data-attachment-id="961" data-permalink="https://jamesmills.co.uk/2019/03/01/beautiful-lebanon/pablo-3/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pablo (3)" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?fit=640%2C320&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?resize=640%2C320&#038;ssl=1" alt="" data-id="961" data-link="https://jamesmills.co.uk/2019/03/01/beautiful-lebanon/pablo-3/" class="wp-image-961" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?w=1024&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?resize=300%2C150&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-3.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li><li class="blocks-gallery-item"><figure><img data-attachment-id="982" data-permalink="https://jamesmills.co.uk/2019/03/24/whats-next-the-toilet-roll-a-reflection-on-the-decline-of-emirates-airlines/pablo-4-2/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pablo (4)" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?fit=640%2C320&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?resize=640%2C320&#038;ssl=1" alt="" data-id="982" data-link="https://jamesmills.co.uk/2019/03/24/whats-next-the-toilet-roll-a-reflection-on-the-decline-of-emirates-airlines/pablo-4-2/" class="wp-image-982" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?w=1024&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?resize=300%2C150&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/03/pablo-4.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li><li class="blocks-gallery-item"><figure><img data-attachment-id="951" data-permalink="https://jamesmills.co.uk/2019/02/28/laravel-timezone/pablo/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pablo" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?fit=640%2C320&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?resize=640%2C320&#038;ssl=1" alt="" data-id="951" data-link="https://jamesmills.co.uk/2019/02/28/laravel-timezone/pablo/" class="wp-image-951" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?w=1024&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?resize=300%2C150&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/02/pablo.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li><li class="blocks-gallery-item"><figure><img data-attachment-id="827" data-permalink="https://jamesmills.co.uk/2017/10/22/laravel-watchable-package/laravel-watchable-social-share-image/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="laravel watchable social share image" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?fit=640%2C320&amp;ssl=1" src="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?resize=640%2C320&#038;ssl=1" alt="" data-id="827" data-link="https://jamesmills.co.uk/2017/10/22/laravel-watchable-package/laravel-watchable-social-share-image/" class="wp-image-827" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?w=1024&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?resize=300%2C150&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2017/10/pablo-3.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li><li class="blocks-gallery-item"><figure><img data-attachment-id="762" data-permalink="https://jamesmills.co.uk/2019/01/12/make-your-bed/pablo-2/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?fit=1024%2C512&amp;ssl=1" data-orig-size="1024,512" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pablo (2)" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?fit=640%2C320&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?resize=640%2C320&#038;ssl=1" alt="" data-id="762" data-link="https://jamesmills.co.uk/2019/01/12/make-your-bed/pablo-2/" class="wp-image-762" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?w=1024&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?resize=300%2C150&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/01/pablo-2.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /></figure></li></ul></figure>



<h2>Using WordPress</h2>



<p>The easiest way (and what I use for this blog) is to use the <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://wordpress.org/plugins/wordpress-seo/" target="_blank">Yoast SEO Plugin</a>. This plugin is a must-have if you are running a blog on WordPress in general. The added bonus is that for every article you are able to select and set an image to use for social sharing. You will see this option at the bottom of the blog editor.</p>



<div data-carousel-extra='{"blog_id":1,"permalink":"https:\/\/jamesmills.co.uk\/2019\/06\/06\/how-to-set-social-sharing-images\/"}' class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1039" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/screenshot-2019-06-06-11-35-50/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?fit=1754%2C1260&amp;ssl=1" data-orig-size="1754,1260" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot-2019-06-06-11.35.50" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?fit=300%2C216&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?fit=640%2C460&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?fit=640%2C460&amp;ssl=1" alt="" class="wp-image-1039" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?w=1754&amp;ssl=1 1754w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?resize=300%2C216&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?resize=768%2C552&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?resize=1024%2C736&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-06-11.35.50.png?w=1280&amp;ssl=1 1280w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>Yoast SEO settings for customised social image sharing</figcaption></figure></div>



<h2>Testing tools</h2>



<ul><li><a href="https://developers.facebook.com/tools/debug/" target="_blank" rel="noopener">Facebook Developer Debug Tool</a></li><li><a href="https://cards-dev.twitter.com/validator" target="_blank" rel="noopener">Twitter Card Validator</a></li><li><a href="https://search.google.com/structured-data/testing-tool" target="_blank" rel="noopener">Google Structured Structured Data Testing Tool</a></li><li><a href="http://www.heymeta.com/" target="_blank" rel="noopener">Hey Meta </a></li></ul>



<h2>Still work to be done&#8230;</h2>



<p>I think there is still a fair amount of work you could do to make sure that the image is optimal for each and every sharing possibility. For a recent project called <a href="https://flightsearches.net/" target="_blank" rel="noopener">Flight Searches</a>, we have hardcoded the meta tags and tried to use optimised images for each service. However, you will still see that some services cut off the text on images if you are not careful!</p>



<figure class="wp-block-image"><img data-attachment-id="1048" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/img_3037/" data-orig-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?fit=980%2C431&amp;ssl=1" data-orig-size="980,431" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;1&quot;}" data-image-title="IMG_3037" data-image-description="" data-medium-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?fit=300%2C132&amp;ssl=1" data-large-file="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?fit=640%2C281&amp;ssl=1" src="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?w=640&#038;ssl=1" alt="" class="wp-image-1048" srcset="https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?w=980&amp;ssl=1 980w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?resize=300%2C132&amp;ssl=1 300w, https://i0.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/IMG_3037.jpg?resize=768%2C338&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" data-recalc-dims="1" /><figcaption>Link share on WhatsApp iOS.</figcaption></figure>



<p>I would love to know your thoughts and how you fit the social sharing images into your blogging routine.</p>



<h2>Update January 2020</h2>



<p>I have just noticed that GitHub offer a nice template for adding social share images to a project. They say images should be at least 640×320px (1280×640px for best display) and offer the <a href="https://jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png">below template</a> to use</p>



<figure class="wp-block-image size-large"><a href="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?ssl=1"><img data-attachment-id="1181" data-permalink="https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/repository-open-graph-template/" data-orig-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?fit=1280%2C640&amp;ssl=1" data-orig-size="1280,640" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="repository-open-graph-template" data-image-description="" data-medium-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?fit=300%2C150&amp;ssl=1" data-large-file="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?fit=640%2C320&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?fit=640%2C320&amp;ssl=1" alt="" class="wp-image-1181" srcset="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?w=1280&amp;ssl=1 1280w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?resize=300%2C150&amp;ssl=1 300w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?resize=1024%2C512&amp;ssl=1 1024w, https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2020/01/repository-open-graph-template.png?resize=768%2C384&amp;ssl=1 768w" sizes="(max-width: 640px) 100vw, 640px" /></a></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/06/06/how-to-set-social-sharing-images/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">769</post-id>	</item>
		<item>
		<title>How to return JSON from Laravel Form Request validation errors</title>
		<link>https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/</link>
					<comments>https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/#comments</comments>
		
		<dc:creator><![CDATA[James]]></dc:creator>
		<pubDate>Wed, 05 Jun 2019 08:28:52 +0000</pubDate>
				<category><![CDATA[Code & Development]]></category>
		<category><![CDATA[Laravel]]></category>
		<category><![CDATA[404]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[laravel]]></category>
		<category><![CDATA[validation]]></category>
		<guid isPermaLink="false">https://jamesmills.co.uk/?p=1026</guid>

					<description><![CDATA[UPDATE 10th June 2019 : I posted this article on LaravelUK Slack channel and David T gave me some valuable feedback. You can force Laravel to always return only JSON by specifying the Accept header However, there may be instances where you want to force it regardless and the below article demonstrates how to do [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><em><strong>UPDATE </strong>10th June 2019 : </em>I posted this article on <a href="https://laravelphp.uk/slack" target="_blank" rel="noopener">LaravelUK Slack</a> channel and <a href="https://twitter.com/davzie" target="_blank" rel="noopener">David T</a> gave me some valuable feedback.</p>



<p>You can force Laravel to always return only JSON by specifying the Accept header However, there may be instances where you want to force it regardless and the below article demonstrates how to do that.</p>



<hr class="wp-block-separator"/>



<p>Recently I have been using <a href="https://laravel.com/docs/5.8/validation#form-request-validation" target="_blank" rel="noopener">Laravel Form Request Validation</a> instead of using inline validation. I find it much nicer to break things out into their own classes as much as possible so I was pleased when this made its way into the core framework. </p>



<p>If you are like me and you cannot get out of the habit of writing inline validation then don&#8217;t worry because the wonderful <a href="https://twitter.com/gonedark" target="_blank" rel="noopener">Jason McCreary</a> has added an awesome feature to the <a href="https://laravelshift.com/laravel-code-fixer" target="_blank" rel="noopener">Laravel Code Fixer Shift</a> to convert inline controller validation to Form Requests. </p>



<p>When using Form Requests with API&#8217;s you will notice that if you hit an API route where the validation fails it will throw you to a 404 view.</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1027" data-permalink="https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/screenshot-2019-06-05-12-02-55/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?fit=2386%2C1728&amp;ssl=1" data-orig-size="2386,1728" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2019-06-05 12.02.55" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?fit=300%2C217&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?fit=640%2C464&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?fit=640%2C464&amp;ssl=1" alt="" class="wp-image-1027" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?w=2386&amp;ssl=1 2386w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?resize=300%2C217&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?resize=768%2C556&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?resize=1024%2C742&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?w=1280&amp;ssl=1 1280w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.02.55.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure></div>



<p>My solution is to make my own <code>FormRequest</code> class which I put in the root API namespace <code>namespace App\Http\Requests\Api;</code></p>



<figure class="wp-block-embed"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist96574240" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-formrequest-php" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-php  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="FormRequest.php content, created by jamesmills on 08:05AM on June 05, 2019."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank" rel="noopener">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="FormRequest.php">
        <tr>
          <td id="file-formrequest-php-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-formrequest-php-LC1" class="blob-code blob-code-inner js-file-line">&lt;?php</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-formrequest-php-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-formrequest-php-LC3" class="blob-code blob-code-inner js-file-line">namespace App\Http\Requests\Api;</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-formrequest-php-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-formrequest-php-LC5" class="blob-code blob-code-inner js-file-line">use Illuminate\Http\JsonResponse;</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-formrequest-php-LC6" class="blob-code blob-code-inner js-file-line">use Illuminate\Contracts\Validation\Validator;</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-formrequest-php-LC7" class="blob-code blob-code-inner js-file-line">use Illuminate\Validation\ValidationException;</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-formrequest-php-LC8" class="blob-code blob-code-inner js-file-line">use Illuminate\Http\Exceptions\HttpResponseException;</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-formrequest-php-LC9" class="blob-code blob-code-inner js-file-line">use Illuminate\Foundation\Http\FormRequest as LaravelFormRequest;</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-formrequest-php-LC10" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-formrequest-php-LC11" class="blob-code blob-code-inner js-file-line">abstract class FormRequest extends LaravelFormRequest</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-formrequest-php-LC12" class="blob-code blob-code-inner js-file-line">{</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-formrequest-php-LC13" class="blob-code blob-code-inner js-file-line">    /**</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-formrequest-php-LC14" class="blob-code blob-code-inner js-file-line">     * Get the validation rules that apply to the request.</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-formrequest-php-LC15" class="blob-code blob-code-inner js-file-line">     *</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-formrequest-php-LC16" class="blob-code blob-code-inner js-file-line">     * @return array</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-formrequest-php-LC17" class="blob-code blob-code-inner js-file-line">     */</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-formrequest-php-LC18" class="blob-code blob-code-inner js-file-line">    abstract public function rules();</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-formrequest-php-LC19" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-formrequest-php-LC20" class="blob-code blob-code-inner js-file-line">    /**</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-formrequest-php-LC21" class="blob-code blob-code-inner js-file-line">     * Determine if the user is authorized to make this request.</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-formrequest-php-LC22" class="blob-code blob-code-inner js-file-line">     *</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-formrequest-php-LC23" class="blob-code blob-code-inner js-file-line">     * @return bool</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-formrequest-php-LC24" class="blob-code blob-code-inner js-file-line">     */</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-formrequest-php-LC25" class="blob-code blob-code-inner js-file-line">    abstract public function authorize();</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-formrequest-php-LC26" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-formrequest-php-LC27" class="blob-code blob-code-inner js-file-line">    /**</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-formrequest-php-LC28" class="blob-code blob-code-inner js-file-line">     * Handle a failed validation attempt.</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-formrequest-php-LC29" class="blob-code blob-code-inner js-file-line">     *</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-formrequest-php-LC30" class="blob-code blob-code-inner js-file-line">     * @param  \Illuminate\Contracts\Validation\Validator $validator</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-formrequest-php-LC31" class="blob-code blob-code-inner js-file-line">     * @return void</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-formrequest-php-LC32" class="blob-code blob-code-inner js-file-line">     *</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-formrequest-php-LC33" class="blob-code blob-code-inner js-file-line">     * @throws \Illuminate\Validation\ValidationException</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-formrequest-php-LC34" class="blob-code blob-code-inner js-file-line">     */</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-formrequest-php-LC35" class="blob-code blob-code-inner js-file-line">    protected function failedValidation(Validator $validator)</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-formrequest-php-LC36" class="blob-code blob-code-inner js-file-line">    {</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-formrequest-php-LC37" class="blob-code blob-code-inner js-file-line">        $errors = (new ValidationException($validator))-&gt;errors();</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-formrequest-php-LC38" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-formrequest-php-LC39" class="blob-code blob-code-inner js-file-line">        throw new HttpResponseException(</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L40" class="blob-num js-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-formrequest-php-LC40" class="blob-code blob-code-inner js-file-line">            response()-&gt;json([&#39;errors&#39; =&gt; $errors], JsonResponse::HTTP_UNPROCESSABLE_ENTITY)</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L41" class="blob-num js-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-formrequest-php-LC41" class="blob-code blob-code-inner js-file-line">        );</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L42" class="blob-num js-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-formrequest-php-LC42" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-formrequest-php-L43" class="blob-num js-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-formrequest-php-LC43" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/jamesmills/3c2fe1fc0d26eefb88c00b3b729f3005/raw/93f167fb9e8ada42aab537093265a501769b3a39/FormRequest.php" style="float:right" class="Link--inTextBlock" target="_blank" rel="noopener">view raw</a>
        <a href="https://gist.github.com/jamesmills/3c2fe1fc0d26eefb88c00b3b729f3005#file-formrequest-php" class="Link--inTextBlock" target="_blank" rel="noopener">
          FormRequest.php
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com" target="_blank" rel="noopener">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>So your <code>SearchController</code> which uses the <code>SearchRequest</code> instead of the default <code>Request</code>stays the same.</p>



<p>We just update the <code>SearchRequest</code> to use our custom <code>FormRequest</code> and not the default and we will get a nice JSON response when we have validation errors.</p>



<pre class="wp-block-code"><code>&lt;?php

namespace App\Http\Requests\Api\Flight;

use Illuminate\Foundation\Http\FormRequest;

class SearchRequest extends FormRequest
{
    ...
}</code></pre>



<p>So now our class will extend our own custom class</p>



<pre class="wp-block-code"><code>&lt;?php

namespace App\Http\Requests\Api\Flight;

use App\Http\Requests\Api\FormRequest;

class SearchRequest extends FormRequest
{
    ...
}</code></pre>



<p>So now when we hit the API endpoint we will get this</p>



<div class="wp-block-image"><figure class="aligncenter"><img data-attachment-id="1029" data-permalink="https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/screenshot-2019-06-05-12-10-39/" data-orig-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?fit=2386%2C1728&amp;ssl=1" data-orig-size="2386,1728" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Screenshot 2019-06-05 12.10.39" data-image-description="" data-medium-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?fit=300%2C217&amp;ssl=1" data-large-file="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?fit=640%2C464&amp;ssl=1" src="https://i2.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?fit=640%2C464&amp;ssl=1" alt="" class="wp-image-1029" srcset="https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?w=2386&amp;ssl=1 2386w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?resize=300%2C217&amp;ssl=1 300w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?resize=768%2C556&amp;ssl=1 768w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?resize=1024%2C742&amp;ssl=1 1024w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?w=1280&amp;ssl=1 1280w, https://i1.wp.com/jamesmills.co.uk/wp-content/uploads/2019/06/Screenshot-2019-06-05-12.10.39.png?w=1920&amp;ssl=1 1920w" sizes="(max-width: 640px) 100vw, 640px" /></figure></div>
]]></content:encoded>
					
					<wfw:commentRss>https://jamesmills.co.uk/2019/06/05/how-to-return-json-from-laravel-form-request-validation-errors/feed/</wfw:commentRss>
			<slash:comments>27</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1026</post-id>	</item>
	</channel>
</rss>
