Skip to content

How I built a dashboard for the iPad with JavaScript

In this post I’m going to show you how I built a signups counter for the JavaScript Course course, so I can see how many people signed up to the course (signups are open from Nov 15 to Nov 22!)

This counter is a totally superfluous thing, the ones that I do when I’m procrastinating and want to avoid the important work.

I’ve been thinking of different ways to do this, like creating an iOS widget with JavaScript, using Scriptable.

But then I thought, well let’s just make a web page. A web page that I can keep open on the iPad, and I’ll put the iPad next to the desk or somewhere I can look at it from time to time.

I can set the iPad to never put the display to sleep, and I can set the page to automatically refresh every 2 minutes.

The advantage of making a simple web page is that I can access it anywhere. From the iPad, the iPhone, the Mac.

I made a Node.js program that fetches the data I need.

The first step is to write a function that gets the data:

const getData = async () => {
  return new Promise((resolve, reject) => {
    let count = 0
    //retrieve the count
    resolve(count)
  })
}

I made it an async function as I use a fetch request, and it’s most likely you’re going to need it too.

If you’re curious, I store all signups into an Airtable record, so inside getData() I put all the code needed to retrieve the count from Airtable.

Then I made a very simple Express server that serves an HTML page that shows the count big, centered in the page:

const express = require('express')
const app = express()

app.get('/', async (req, res, next) => {
  const count = await getData()
  const html = `
  <html>
  <head>
    <!-- refresh every 2 minutes -->
    <meta http-equiv="refresh" content="120">
    <!-- allow full screen on iOS -->
    <meta name="apple-mobile-web-app-capable" content="yes">

    <link href="https://fonts.googleapis.com/css2?family=Arvo:wght@400;500;600;700&amp;display=swap" rel="stylesheet" media="all">
    <style>
    html,
    body {
      font-family: Arvo,Helvetica,Apple Color Emoji,Segoe UI Emoji,NotoColorEmoji,Noto Color Emoji,Segoe UI Symbol,Android Emoji,EmojiSymbols,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Noto Sans,sans-serif;
      margin: 0;
      font-size: 200px
    }
    h1 {
      display: grid;
      place-items: center;
      height: 100vh;
    }
    @media (prefers-color-scheme: dark) {
      body {
        filter: invert(100%);
        background-color: #000;
      }
    }
    </style>
  </head>
  <body>
    <h1>${count}</h1>
  </body>
  </html>
  `
  res.end(html)
})

const listener = app.listen(3000)

Here’s the result:

And here’s the same page on the iPhone:

You can run the program locally on your computer and you can access it from devices on the same wi-fi network, as long as the computer is running, or if you prefer you can use a localhost tunnel service, but you can also put this somewhere on the Internet.

I put the app on a server I use for my Node scripts, so I can access it from anywhere, even if I’m on a 4G network.

If I want, I can also AirPlay that on the Apple TV, so I can see the number of signups on the big television screen.


→ Here's my latest YouTube video

→ Get my JavaScript Beginner's Handbook

→ I wrote 17 books to help you become a better developer, download them all at $0 cost by joining my newsletter

JOIN MY CODING BOOTCAMP, an amazing cohort course that will be a huge step up in your coding career - covering React, Next.js - next edition February 2025

Bootcamp 2025

Join the waiting list