We are here, 2021 has arrived, and I hope you all had a brilliant festive period, and 2020 is in the rearview mirror.  Don't get me wrong - 2020 has been a tough year for everyone, but I think there is some good to come out of it.  I think it has allowed us to reset what it means to be human.

Towards the end of 2020,  I was starting to look into Next.js - A framework that had a significant release recently.  It is a fantastic framework that makes it easy to build server-side and static applications using React.  I highly recommend checking it out as I am sure it will be big in 2021.

What am I building?

In January, I want to achieve three objectives: (i) drink no beer in January, (ii) exercise more, and (iii) practise more mindfulness.  I thought it would be fun to build a simple application using the JamStack using NextJs with a simple Airtable backend. I also wanted to be able to easily view and update on the challenges on a mobile device.  

The idea would be to see what I could achieve over a weekend.

TLDR - Click here to view the finished app.

Step 1: Airtable - Data

I started by designing the data model that I would require to build the application. Airtable is a low code solution to building collaborative apps, what attracted me was its straightforward approach to getting started and a REST API to integrate into my application.

The first attempt at a solution didn't work too well and restricted it to the three goals I had created without the ability to scale. This is mainly due to designing it as if I was doing it in a spreadsheet.  Airtable is actually a relational database, so I went back to the drawing board and came up with this simple schema.

Airtable Schema

Whilst it could be normalised further, for now, this works and allows me to easily add new goals as and when I come up with them.  I also wanted to display updates to my audience, so I created a simple blog table to contain my updates.

Step 2: Test The API

Before writing the application, I wanted to test the API out.  The API documentation is excellent, and we can use Postman to test the API and check the shape of the data coming back is expected and ok.

Airtable API

Step 3: Building The Application.

As mentioned, I decided to build the application in NextJs.  The first step is to create a new skeleton app and remove all the stuff we don't need.  This leaves us with a blank template to work from.

I started looking at CSS Grids for the layout - I wanted an elegant way to create a responsive application without using media queries.  The layout is pretty simple so figured I could achieve this easily. The secret is using the following CSS code.

display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));

This allows us to create flexible grid tracks with a minimum of 350px and a maximum of 1 fraction of the remaining space.  To understand how this works, Mozilla Developer Network has a fantastic explanation on this and CSS Grids in more detail.

By default, NextJS supports CSS Modules. However, I recently came across EmotionJs, which is a CSS in JS implementation. CSS in JS has the following advantages.

  • Local scoping: Reduces CSS clashes around the project.
  • Portable: Easily moved around.
  • Reusable: Write once and reuse multiple times.
  • Dynamic: Apply logic to your CSS.

I decided to use Styled Components, and an example of how I used this can be seen below in implementing my progress bar.

const Progress = styled.progress`
    border-radius: 7px;
    width: 100%;
    height: 22px;
    box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.2);

    ::-webkit-progress-bar {
    background-color: #eee;
    }

    ::-webkit-progress-value {
    background-color: ${(props) => props.barCl};
    }
`;

This creates a component called Progress that is a styled implementation of the html5 progress bar.  When we use this component in our code, it takes on the CSS we define for our component.  As you notice we are accessing a props property called 'barCl'.  We can now use this as a regular React component as such passing in the props required.

<Progress
    value={challenge.fields.ProgressTotal}
    max={challenge.fields.Target}
    barCl={challenge.fields.BarColor}
/>

You might notice BarColor is coming from my data.  This is a decision to easily change the progress bar's value for each challenge by setting a value in the database.  This is a pattern I reused throughout the application to make the application as dynamic as I needed it to be.  In the example below, the border, progress car and units are all defined in the database.

Challenge Grids with customisable Text, Colours and Progress Bar

The final exciting piece of the puzzle that I liked was the use of getServerSideProps.  This allows NextJs to get data from the Airtable API and give it to the component to be rendered via props.  This allows the application to be run as Server-Side Rendered (SSR) application.  SSR means the pages are generated at runtime on the server and deployed to the client.

Step 4: Auto Deployments

One of the neat features that the team who have developed NextJs is they own Vercel.  Vercel is a cloud platform for static sites that can be automatically deployed and scaled.

I connected my git repository to Vercel that automatically creates a build from my master.  Going forward, any changes I make to master will be automatically detected by Vercel and deployed with an optimised production build.

However, one of the most significant features is preview builds.  Preview builds allow separate branches to have their own deployed instances.  This allows us to check how the code works on the deployment server and ensure there are no breaking changes.  Once satisfied everything works ok, tests are passing we can create a pull request into master.  Once completed Vercel will deploy the changes to production automatically.

This workflow makes it simple to develop, test and deploy our code automatically.

Wrapping Up

So there we have it, a weekend experiment to try out several technologies I have been looking at for a while.  I am pretty pleased with how it came out and enjoyed learning about the following tech:

  • NextJS;
  • Airtable;
  • CSS Grids;
  • Styled Components with EmotionJS;
  • Server Side Rendering;
  • Vercel Deployments.

The application is successfully deployed automatically on the Jamstack and has taken on a retro theme from the computer game era of my childhood.

Of course, several improvements can be made, but the application is functional as an MVP, and if you are interested can be found at https://challenges.matt.scot.

Thanks for taking the time to read and have a wonderful 2021.