The concept

I was at a BristolJS talk about Vue.js recently and the developer speaking was praising CodeSandbox.

I’ve tried CodeSandbox in the past and not really enjoyed it, maybe I just didn’t really understand the whole Node stack very well. After also hearing about it a lot last year at Vue.js London I thought I’d give it another go.

Whilst away with my daughter a few weeks ago, we were driving through a dark, spooky country lane with trees that arched over the road. She got a bit creeped out by it so I suggested she pretended the sat nav was the control panel on our spaceship, allowing her to blast any baddies with the onboard lasers, torpedos, flame throwers etc.

This worked a treat. She was happy, excited and the built in Sat Nav is rubbish so I didn’t need it anyway.

I wanted to build a control panel as a web site that we could take anywhere and use on any device. This would still get my kids imaginations flowing (it’s just buttons and sliders, they still have to look at the real world and think) but would be an easy catalyst to destroy boredom or fight off baddies on a creepy country road.

Later that evening when I went to bed, I got my iPad Pro and Microsoft Foldable Keyboard (which I bought half price on Amazon and am very happy about that) then logged onto CodeSanbox.io. I was excited, the idea was fresh in my head, but I was away and only had the iPad, so CodeSandbox was the logical answer.

Building the app

Prototyping

In order to get something done before the return car journey the next day, I had to be quick.

I’ve learnt that all projects take longer than I think, so I really tried hard to keep it simple. There was going to be a radar, grappling hook, animations etc, but as I was working in a rush I stripped it right back to basics.

I never finished this until last night… so about a month longer than the 1 day I had planned.

I want to do hand drawn buttons, icons, metallic screws “bolting” the panel down, but for speed and to get something running at the time I went with Bootstrap. The kids don’t care at all, they’re just happy with buttons that make things happen… but I’m still going to do custom graphics one day.

So I quickly started a Vue.js template in Sandbox and cobbled together a basic UI in HTML, lots of copy/pasting after importing Bootstrap. CodeSandbox makes this all very easy, it’s all done in the UI with obvious buttons and search boxes for common dependencies.

It wasn’t long before I had the markup looking acceptable enough.

Wiring it all up

As usual with all projects half your time is spent doing about 90% of work, and the other half is doing the remaining 90%. At least.

I constantly find that when I think I’m nearly finished I have to spend the same amount of time fixing bugs, re-working my logic, taking out features that aren’t necessary and re-working the UI.

Anyway, thanks to Vue.js it was easy to keep the markup near enough how I had it and just tweak the logic for the individual components till they played happily together.

Using seperate .vue files made it easy to break things up when it got complex and the app was never going to get to the stage where I needed Vuex

It was still only hours though to put it all together, a little on the first evening and a bit more over lunch the next day.

By the time I had to leave the for the return Journey I had a very rough page loading in the Safari on my iPhone!

User Testing

I handed the phone to my daughter, unlocked, with the page loaded in Safari for her to play with. She was very happy and got straight to destroying the baddies!

Success! I thought… briefly.

The app was fine but she kept switching tabs, or minifying the page, or trying to re-load by scrolling down the page.

It didn’t work well as a website with a child bashing away at the screen enthusiastically.

This is part of the extra 90% of work… testing, refactoring, extra features, deployment. I’m not so good at predicting all that stuff.

What I learnt from the short round of user testing was…

  • the app works fine
  • the native browser UI needs hiding
  • it needs to work offline
  • it needs a home screen icon so it can be easily re-opened

Fortunately me for me these are basically all solved by turning it into a PWA… which CodeSandbox basically sorts out for you in the first place (all via vue-cli under the hood I think)

Round 2

I’ve never made a PWA before, I tried with create-react-app but totally failed, currently Pokésquire is not a PWA.

A bit of googling though and I realised there’s a bit more to it than just ticking a box saying “yes make me a PWA”.

Either, I added this to the index.html of it was added for me…

<script>
	if ("serviceWorker" in navigator) {
      navigator.serviceWorker.register("/sw.js").then(function() {
        console.log("Service Worker Registered");
      });
    }
</script>

Then I updated that sw.js file to list the assets that would need downloading to work offline. I can’t even remember where this snippet comes from (let me know if I pinched it from you so you can have credit… otherwise it’s probably from CodeSandbox) but it does all the saving offline stuff, I just had to add the list of assets at the top

var cacheName = "travel-control-panel";
var filesToCache = [
  "/",
  "/index.html",
  "/main.js",
  "/bootstrap/dist/css/bootstrap.min.css"
];
self.addEventListener("install", function(e) {
  console.log("[ServiceWorker] Install");
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      console.log("[ServiceWorker] Caching app shell");
      return cache.addAll(filesToCache);
    })
  );
});
self.addEventListener("activate", event => {
  event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", event => {
  event.respondWith(
    caches.match(event.request, { ignoreSearch: true }).then(response => {
      return response || fetch(event.request);
    })
  );
});

I’ve not made icons for it yet, so I didn’t need to do any of that, I just had to update the manifest.json file to remove the browser UI and set a nice app shortcut title:

{
  "name": "Weapons Control Panel",
  "short_name": "WC Panel",
  "display": "standalone"
}

This all works ok on my iphone and ipad, I probably need to do some more Android testing.

Deployment

I was at a point now (about a month later) where I was ready to deploy this probably to a URL and tell my friends to use it with their kids as well.

CodeSandbox seems to encourage deployment with Zeit and Netlify wiht the simple click of a button. Given I’d never heard of Zeit and heard Netlify a couple of times, I went with Netlify.

It was very easy, it was the click of a button to deploy but it gave me a url like CodeSandbox’s. It was just a hash in front of netlify.com

There was however, a lovely “Claim site” button. I clicked this, attached my Github account and quite quickly guessed my through the rest of the process to attach my custom sub-domain:

Claim Site button

The problem was, somewhere during the process I’d attached the Netlify site to the Github repo, which is really just the source code and this is what I was seeing at http://weapons-control-panel.willshawmedia.com

Site 404ing

When you deploy from CodeSandbox, your app gets built for you and a production version gets deployed at the hashed URL.

As I’d switched the netlify site to copy files from Github, it now longer had a production site to deploy, I realised I had to tell Netlify to run the npm run build command and deploy the code from a build folder…

I did some googling and found this, and did what it said without really paying much attention

npm run build creates a build directory with a production build of your app. Set up your favourite HTTP server so that a visitor to your site is served index.html, and requests to static paths like /static/js/main..js are served with the contents of the /static/js/main..js file.

https://facebook.github.io/create-react-app/docs/deployment

Deploy settings on Netlify

This did make my production build, but it did not put it where I was expecting (which is fair enough because I wasn’t using Create React App!)

So I looked at the logs… they’re very helpful logs, should have done that much earlier!

Log showing dist not build folder

Pointing the “Publish Directory” to the right place resulted in this…

Success, the page loaded

WOOHOO! I did it! I’ve deployed it, it’s live, it’s working, it’s finished and it bloody saves to the home screen and still works in airplane mode!

A couple more things..

A week later, once I’d come down from my high and been told by up to 2 people wonderful things like “this is fun”, I decided to add a couple more “finishing touches”.

I added Google Analytics, a fixed footer for cookies (which I pinched from CSS Tricks) and tagged a release on Github, for the hell of it. I like making releases.

Final thoughts

Code sandbox is great for prototyping. I could work pretty well with my iPad Pro and Microsoft Folding Keyboard but neither are a replacement for my desktop PC, VS Code, npm running in powershell etc etc.

When I’m away and I have an idea like this or if I need to tweak something, it’s great ot know I can use CodesandBox on the go (even on someone else’s computer as it’s all cloud based).

Version 2+ of Weapons Control Panel will most likely all be developed in VSCode though.

Netlify was a wonderful surprise though, it’s great that it’s hooked up to Github for me and I don’t need to do anything to deploy it.

I’ll add some testing with Jest soon and I’ve just created a deploy branch for it, but I’ll definitely look at Netlify again in the future.

I’ve also got a better understanding of PWA stuff now, it’s given me an idea of what I was doing wrong on Pokésquire.com so I’ll go back and try and sort that out now.

How much use this gets and how well this works on a few devices is going to determine how much more time I spend on it now. If it gets enough use I’ll sort out a proper app icon and some artwork for it, and sell it to all the parents in the world and make millions.