How to Code a Progressive Web App News Website

James Y Rauhut
We’ve moved to
5 min readSep 15, 2017


For the last two weeks, I worked on a personal project called The Global Upvote. The Global Upvote aggregates top voted stories from across the web, summarized and updated every sixty seconds.

This article focuses on how I was able to implement The Global Upvote for aspiring developers. I wrote a separate article about design process behind this. These two stories may seem completely separate. But the design and development process was deeply intertwined in real life.

Note that I’ve written a sister article about how to design this Progressive Web App news website here.

Finding the Data

In design, there is a concept of content-first. Content-First Design says you need to design around the content. For me to do that, I needed to ensure I could grab the correct data. Before I started on any of the actual front-end work, I worked with the Reddit API and my Node server.

I knew there were two parts of content I wanted to capture from Reddit:

  1. The top posts of r/WorldNews for their headlines
  2. A bot user’s comment that summarized the story
These objects were sweet, sweet Reddit data.

Luckily, there was a great Node wrapper for the API called Snoowrap. It was easy to use and had me getting content in no time.

One big thing I learned on this project was request management. In the past, I had used my Node server as a API requester every time a user would visit my app. But, I had an obvious epiphany.

I could hold on to the small amount of data (stories) on my server and update it once a minute with a simple setInterval. This stopped pushing the risk of abusing my Reddit API limits and shortened story load times because I would not have to ping the Reddit API every time.

Keeping It Progressive

Wanna know the cheap, dirty secret about making a progressive web app in React? Just use Create-React-App. The contributors on that project have done a wonderful job of adding service workers for near-instant loads and a manifest file for your meta data, and optimizing the Webpack bundling the best they can. In the past, I had to do a lot of work for PWAs ( Progressive Web Apps) and even wrote a tutorial on perfecting them.

This was the first time I worked on an offline-friendly mode for Chrome and Firefox to do stuff like read articles before my computer connected to wifi.

The first half was to do things whenever the internet connection changed using event listeners. That way, a new connection to the internet could trigger fetching stories, and a lost connection could notify the user they are offline.

The second half of offline-mode was saving new stories to the user’s device every time they were fetched. This was my first time using LocalStorage, and I was pleasantly surprised by how easy it was.

A last bit of the PWA to get done was improving the perceptual speed index. You can see this user-centric metric by opening Chrome DevTools and running an audit. To improve this score, I made skeletons that would appear when my app’s state was fetching.

Plugging a Plugin

I had determined that I wanted the user to be able to save the experience as their new tab for Chrome and Firefox. The browsers natively support setting a home page. But that does not give you control of the URL bar immediately. This was an important detail because a user does not want to have to click the URL bar every time they open a new tab.

I feared that I was about to dive into the deep-end of browser extension development. This was something I was not familiar with besides a grid checker to help my visual skills. Once again, this solution ended up being handed to me on a silver platter. Google includes a similar extension in their sample downloads. I was working in no time with the Global Upvote Tab Extension. No changes were even needed for the submission to Firefox’s store!

The Final Outcome

From a development standpoint, I loved all the different solutions I could put together for The Global Upvote. These solutions tell me that the web community is getting better at working together to make development experience less frustrating. Acing the Chrome DevTools Audit, formerly the Google Lighthouse Extension has also gotten the easiest it has ever been.

All source code has been open-sourced in case you want to dig around or make it work for you.

Several quick things to note:

  • Where are the CSS files?!
    There are none. I use Styled Components to attach styles directly to their component!

    Check out this talk I gave at IBM about why CSS-in-JS is insanely good:
  • Where is the source code for your tab extension?
    Check it out in the separate repo for Global Upvote Tab.
  • How do I get started running this locally?
    Check out the documentation for Create-React-App if you haven’t already.
    Much wow. You also need a file called keys.json in the root directory with your information for Snoowrap. It should look like this:
"userAgent": "random-term",
"clientId": "FromYourRedditAPISettings",
"clientSecret": "FromYourRedditAPISettings",
"username": "YourRedditUsername",
"password": "YourRedditPassword"

I hope you enjoyed this case write-up!

Again, I’ve written a sister article about how to design this Progressive Web App news website here.

For further information: Feel free to contact me by the comments, email, or @seejamescode. I work in ATX for IBM Design and always love conversation with the web design community. Leave any questions you may have and I will try to answer them for you!



James Y Rauhut
We’ve moved to

UX Designer & Engineer. Founder of Poster.Party, working at Pingboard, and started at IBM. Blogging about PWAs, accessibility, and more at: