How I Built a Chrome Extension Loved by over 9,000 10,000 15,000 Parents Update (2nd December 2025): Since I published this article the Christmas rush has hit and we are now up to over 10,000 users! Update (18th March 2026): We're now up to 15,000 users! Summary I built MYO Studio to scratch a personal itch while making Yoto cards for my kids. What began as a quick hack is now a Chrome extension…
Partnering with Sencha I delivered a 7 part series of webinars where we built a cross-platform Email Client with Ext JS (both classic and modern toolkit). This detailed all the steps needed to build this detailed application from start to finish. I covered both toolkits to give an excellent experience on desktop and mobile. We covered View Controllers, View Models, Grids, Forms, Windows, Trees,…
I made a challenge for myself to post a quick Chrome Dev Tools tip on Twitter everyday for 30 days. Browse them all below! ⚡️Chrome Dev Tools tip: On any tab hit CMD (or CTRL) + P to be able to find and open any file that's been loaded. Great for jumping quickly to source files. pic.twitter.com/zmkydlzuvY — Stuart Ashworth (@stuartashworth9) June 23, 2021 ⚡️ Chrome Dev Tools tip: You can use…
A few weeks ago I launched a wee website that shows you all the Number 1 songs on your birthday . It does so by scraping the Official Charts website grabbing the chart topper on your birthday each year. This worked well but wasn't very fast - especially as you get older! I decided to write a quick script to go off and gather all the data for each day between the chart records starting (in 1953)…
I recently launched a daft wee side-project to show people all the Number 1 songs on their birthday . To collect the data I had to scrape the Official Charts website as there was no official API available. This article is going to explain how we can use Cheerio to scrape the site and gather all the information we need. The full code for the site is available on GitHub Requirements We're trying to…
I recently launched a daft wee side-project to show people all the Number 1 songs on their birthday . From there you can turn it into a Spotify playlist to listen to them all! The full code for the site is open source and available on GitHub . I'll be writing up a few articles on some of the tech used to build it, starting with: How to Scrape a Website with Cheerio How to Batch Process Promises…
There's a quick config that we can add to the vue.config.js file to disable source maps from being generated when producing production builds. We simply add productionSourceMap: false to the config. Our file should look something like this: // vue.config.js module . exports = { ... productionSourceMap : false , ... } ; It's as simple as that!
When composing a Vue.js interface of lots of sub-components we often want to make a few small styling tweaks to those sub-components without making changes to that component directly - either because we can't cos it's a 3rd party component, or because we don't want that change to apply everywhere. The scoped Attribute If we're using scoped component styling then what appears to be a simple task…
We all know how to add a listener to an event coming out of a Vue.js component, right? < my-toolbar @action-clicked = " onActionClicked " /> Dead easy. This will execute the onActionClicked method when the action-clicked event is emitted from the my-toolbar component. The onActionClicked method will receive the parameters passed from the $emit call within the component. For example, the $emit…
We all know that we can define parameters on Vue Router route paths which are then parsed and made available in the $route.params object. We can take this a step further by restricting the patterns that these parameters take by using a regular expression. This has a couple of benefits - it pre-validates the parameter so we only reach the route with a correct parameter value, and it also allows us…
I recently faced a problem in a Vue.js application that I'm working on where a component had a toolbar that had some standard buttons and a slot so extra options could be added. I wanted to show a small divider between these standard buttons and any extra ones added by the slot, so I added a span in-between them and the slot. < div > < button > ... </ button > < button > ... </ button > < span…
I saw a tweet recently ( unfortunately I can't remember which one! I found it! I've embedded it below 👇!) that mentioned someone demonstrating to a colleague how to use the debugger statement in dev tools and how it blew their mind. I thought it would be useful to run over all of the other hidden ways we can debug our JavaScript code in Dev Tools. I just taught a good developer with 5 years of…
I always forget which way round to put the key and the renamed variable so this post is as much for my reference as yours! When destructuring an object we might want to use a different name for the variable instead of the existing key. This might be because the same name is used already or the key doesn't match your linting rules. We can easily rename it by using the following syntax: const item =…
Sometimes our objects will have different properties and we want to consume them in the same way. Rather than having to handle undefined s everywhere we can give a destructured variable a fallback default value for when it's missing. To do this we simply suffix the variable name with the default value: const item = { id : 1 , name : 'Stuart' } ; const itemTwo = { id : 2 , name : 'Stuart' , title :…
So many icons have an ingrained meaning to us that when we use one on a button the action that will be triggered is second nature. This is great for decluttering our interfaces as we can omit lots of lengthy text descriptions from the buttons. You will probably be familiar with this approach to add an icon using the Font Awesome library: < button > < i class = " fa fa-refresh fa-2x " > </ i > </…
The v-for attribute allows us to repeat a piece of markup for each item in an array. The example below shows a list being populated from an array of objects. < ul > < li v-for = " item in items " :key = " item.id " > : </ li > </ ul > To show the name and id properties of the item object we use the familiar item.id and item.name syntax. If we were handling this object in plain JavaScript code we…
Most charts are fairly inaccessible due to their graphical nature and we should provide an alternative way for users of assistive technologies to consume the same data. In Freelance Insights I added a simple chart showing the trends of various stats over the last 12 months. This is a very simple graph and is rendered with Chart.js which uses <canvas> to draw the chart. Dead easy for us developers…
Ext JS Models ( Ext.data.Model class) defaults to having an ID property named id . This field will be automatically created for you and be mapped to the id field in your incoming data. By knowing where the unique key for the model lies we can make use of some handy methods on the model, such as getId , and findById on an Ext.data.Store instance. In this snippet we can see that 3 fields are created…
When displaying images in our web applications we never want to see a dead image shown when an image file has been moved or deleted. This can become a more prevalent problem when we are using dynamic image URLs or convention based URL structure. For example, we might always load a User's profile image by combining their ID number and Last name to form the filename and always looking in a specific…
This is an adapted extract from my new eBook - Ext JS 6: Getting Started . Pre-order it now and get 30% off ! One of the bottlenecks of my workflow when working on the styling of a Sencha app is the time it takes to make a SASS change, wait for a Sencha build (either via sencha app watch or a full sencha app build ), refreshing the browser and then navigating to the relevant part of my app. This…
This is an extract from my new eBook - Ext JS 6: Getting Started . Pre-order it now and get 30% off , or download a sample chapter ! The unification of Ext JS and Sencha Touch in this new framework has introduced a number of new concepts and possibilities for developing applications. This iteration of Ext JS isn’t so much an iteration of the development framework itself but a leap ahead for the…
IntelliJ has a lot of powerful features that help improve our overall development workflow. One feature that I use everyday is Live Templates . This article will discuss how to use Live Templates to speed up your development and stop you getting RSI. What are Live Templates? Live Templates are code snippets that can be inserted into a code file using a shortcut ‘key’ which is expanded into the…
I'm excited to announce the launch of my new email course - Best Practices for Improving your Sencha Apps - which delivers 7 lessons to your inbox on how to improve your Ext JS and Sencha Touch apps. Let me talk you through how to avoid the most common problems developers face, how to improve your workflow to maximise your efficiency and make sure your code is of the highest possible quality.…
This week saw the announcement of the sessions running at SenchaCon 2015 , which includes a big announcement about the future of the Sencha product landscape - “the merge”. That's right, Sencha plan to merge Ext JS and Sencha Touch into one uber framework that will allow us to develop apps to target desktop, mobile and tablet devices with just one framework. This is a big leap forward and…
I've been through many different Chrome Extensions to allow me to grab colours from webpages but none of them ever stuck as being a reliable solution (perhaps I didn't look hard enough…). Recently I've reverted to screenshotting the page and then opening in Photoshop… ugh. But fear not! The Chrome team have done it again and baked this feature right into Developer Tools. So here's how you use it.…
This article is going to discuss how we can approach controlling application flow in Sencha Touch and Ext JS applications using domain-specific events rather than relying solely on standard framework events. By following this technique you will make your applications more flexible, reusable and allow refactoring to be done with less impact. What do I mean by controlling application flow? When I…
The Problem The rise of the mobile web over the last half decade or so has meant that our website testing, that once, not that long ago, generally involved 3 or 4 browsers across 3 or 4 operating system versions, has now grown to a hand-full of browsers, spread countless operating system versions all running on what seems like infinite hardware variations. To top it all off these OS versions run…