All Projects

Lolbaron.com

lolbaron.com website screenshot taken on desktop.

A league of legends app that shows player match history and game statistics.

Technologies

  • bulma.css
  • sass
  • react
  • next.js
  • redux
  • google tag manager
  • google analytics
  • google workbox
  • express.js
  • AWS
  • nginx
  • pm2
  • cloudflare

This project is the largest project I made and it took a lot of time and effort but I really enjoyed it as I did and planned everything from scratch. I was thinking I must do something bigger to show my skills and to learn more so I started searching for an idea and as I was a league of legends diamond player and I liked champion.gg website I decided to create a similar website but with a modern stack.

Notes:

  • I noticed that my Next.js app some times go down and respond with 500 internal server error so i used AWS CloudWatch metrics to monitor this error and i found large spikes in CPU usage so i setup custom metrics to check memory usage and i found out that this happens because the system runs out of memory and i made sure of that using dmesg command on the instance and i found out that the system killed the next.js node process because of out of memory. Upgrading to an instance with more resources than t2.micro would solve the problem.

  • The champion.gg API is down for a long time now and it made most of my app features unusable (except searching for a summoner match history as it's directly fetched from League of Legends API) as I totally depended on it and this is a lesson learned the hard way to never depend on a free API made by a small company. You can check some old screenshots for the app in development in my google drive LOLBARON old screenshots in development.

Steps to create the app:

  • I started with a normal CRA(create react app) but then I realized that I must use SSR (server-side rendering) because an app like that needs SEO. I was confused about which way should I use (Next.js, After.js or just do it from scratch) but I ended up using Next.js after some research as it has a big community, great documentation, very active development and used by many companies.

  • I created a custom server using Express.js to handle custom routes.

  • I created an API to consume endpoints I need from League of legends API and Champion.gg API as they didn't support CORS and I needed to fetch data both on server and client-side. You can check the API source code here: lol-api

  • Some of the data fetched from those APIs changes frequently and some changes every few hours and some changes weekly. I didn't want to abuse those free APIs so i decided to use Redis as a very fast in-memory database to store the data fetched and give it expiry depending on its type for example:

    • Summoner match history is fetched whenever a user search for that summoner and stored in Redis with a month expiry and only renewed before that on user demand (if he clicked update button in the web app).

    • Static data about items, champions, summoner spells and runes only changes when the game updates so i made a cron job to check league of legends version once every week and if it changes fetch this static data again and store it in Redis.

    • Champion.gg API data changes every few hours so i didn't need to fetch them every time a user open the site so i made a cron job every few hours to get this data and store it on Redis.

  • I wanted a CSS framework that doesn't use Javascript or JQuery so i can easily intergrate it with React and after some research i found Bulma.css which had everything i need.

  • I wanted to make sure that my API can only be accessed from my app so the first time a user visits the app a JSON web token is created and sent with the requests to the API using the same secret in both servers and in the response send a signed cookie to the user browser so that in subsequent visits he is automatically verified to be a user and allowed to use the API.

  • I used the next-offline plugin which uses google workbox to make the app works offline and added site.webmanifest to make it installable on a mobile home screen and opens on a full screen like a native app.

  • I used GTM (Google tag manager) to handle analytics using on history change trigger and I even added a custom dimension to track online vs. offline interactions and Using a custom metric to track time that analytics requests spent in the queue before they are resent when the user is back online. Using the workbox-google-analytics package I managed to enable offline analytics.

  • I created the app logo using Gravit Designer and then I generated all necessary icons needed for different platforms and browsers as following:

    • Two icons for chrome on android 512x512 icon to be used as a splash screen and 192x192 icon as a home screen icon.

    • Apple touch icon 180x180 with a white background and some padding for the IOS home screen.

    • SVG to be used in the Safari pinned tab.

    • An Open Graph Protocol Image using a white background and a 1.91 aspect ratio as recommended by Facebook.

    • Favicons: 16x16 png, 32x32 png, 32x32 ico.

    • browserconfig.xml file which links to 150x150 image to be used as a tile for the web app on windows.

  • I added SEO support for both search engines and social media following the best practices as following:

    • Added these meta tags keywords, og:site_name, og:type, og:image:width, og:image:height to a custom Document component extending the default document provided by next.js in _document.js file because they will be shared across all pages.

    • For each page, I added dynamic meta tags that are different for each page like title, description, og:title, og:description and even in each champion statistics page i used the champion splash art from league of legends static API as the og:image instead of the default image.

  • After finishing the app it was time to deploy both the app, the data API and the database I decided to use AWS especially that it's widely used and has a one-year free tier. I created 2 private repositories on AWS CodeCommit for the data API and the app. I used an EC2 t2.micro with ubuntu 18.04 as the operating system to run both the app and the data API and used pm2 to handle the deployment and restarting servers on crashes and used Nginx in front of them as a reverse proxy. I used an Elasticache Redis instance instead of installing Redis locally on the EC2 instance as I did in development on my local machine.

  • Getting an agreement from league of legends that I can deploy the app in production.

  • I registered the domain name lolbaron.com from AWS route53 and used Cloudflare to get a free DNS, CDN, SSL and DDoS protection and of course much more features available on their web app like analytics and page rules.

As you can see this was a fully-featured app created from scratch by me it was a great learning experience and a greater feeling of achievement when I had finished the app and saw it in production.