I am really happy to share with you that a website that I recently poured a lot of my heart into has just reached 12k visitors! I'd like to share with you the process and my learnings.
The website, Feminist Covid Response, is a volunteer online data repository of information on feminist principles and actions, as well as policy responses to the COVID crisis. Together with Annie Souza we volunteered our time and tech skills for Women's Environment and Development Organization to bring this to fruition.
Read more about:
- See demo 🖼
- About the Website 🖥
- The Process 🗺
- Challenges and Fixes 💡
- Key Take-Aways 📚
You can explore the page on your own or just see it here:
The website was created together with Annie Souza for Women's Environment and Development Organization and it has been continuously visited by folks from 157 countries totalling to 12k visits over 1 week!
It is really humbling to see that our app has reached folks literally around the world:
It's not only great because it flatters our egos — more importantly, it shows that these subjects are important to so many people and that the work that went into making this website responsive, accessible and light paid off. Learning to code in the US, one oftentimes forgets that not the whole world uses iphones or macs and that (sadly) there is a portion of folks who still feel comfortable with Internet Explorer.
Annie and I received wireframes from WEDO, together with the deliverables. The NGO prioritized these features:
- it should be light for folks who have limited data;
- it should be available in three languages (both the static and externally-fetched data);
- it should be accessible;
- it should be ready in two-three weeks;
- the solutions should be cheap (free) and sustainable as there's no budget.
It was a great challenge not only because of the time constraints but also because of some of the features we always wanted to implement but never had time to do so. We were really excited that we were building something that was designed to be responsive, international and accessible.
Our backend is Ruby on Rails hosted on Heroku:
- Ruby on Rails
- PostgreSQL - database
- Active Record - Object Relational Mapping system
- Active Model Serializers - serialization
Initially, because we worked with a third volunteer dev, our backend was Contentful, which seemed like a great idea given that it is a CMS (Content Management System) and it would be possible for the volunteers to just directly add entries there. However, we hit a wall after a wall trying to migrate 1,500+ entries from excel sheets (crowd-sourced by volunteers) to the database. Given time pressure, we gave ourselves deadline to try out different approaches from their docs, stackOverflow and their slack and as none of that seemed to work, we just set up a new backend, which ironically took less time than the research on Contentful. Below you see the domain model:
Our frontend is React hosted on Netlify:
Initially, we wanted to use Tailwind for CSS but given that back then we already assumed we'd need to learn Contentful and also prioritized working with React Hooks, we decided to work with what we were most comfortable with: pure CSS with good ol' media queries. We tried to make sure our components would be reusable but not unresonably abstracted. Below is our component hierarchy:
Despite full-time job, Annie and I decided to work on this project every day. We would start the day with a slack stand up where we'd discuss next steps and distribute tasks for the day, and then would have an in-person stand down where we'd update each other on the progress, update Github issues and perhaps debug some parts together.
Once a week, we'd have a meeting with a WEDO representative for updates and feedback. Every few weeks, we'd have a new portion of data to migrate to the database.
When it comes to the git workflow, we'd follow this practice:
- the git repo belongs to the organization and we are both added there as collaborators;
- there are two standard branches:
- whenever you start working on the new feature, navigate to
git pull origin dev, then
git checkout -b nameOfTheFeature; this is the branch where you'll push the code;
- once the feature is “done” and you checked whether it’s not bugging out, merge it to
devand request review;
- if it’s okay, the other person merges it to
masteror you both merge it together and hold a little merge party;
Initially, we were open to feedback from a few different stakeholders at WEDO but given the quick pace and time pressure, that became a bit messy. We pivoted and had one contact point at WEDO who was responsible for gathering all the feedback and presenting it to us.
Now that our work is done and WEDO actually is able to work with a web agency where people have only one job, we are handing this project over. In order to do that, we prepared exhaustive docs and will hold frequent communication.
While the menu and some static parts of the page are translated using localization package, we also need the fetched data to appear in the correct language. Initially, we wanted to rely on Google Translate API for translating the backend data. It turned out that Google Translate is not free and given the traffic on the website, it could actually become quite costly and inefficient. Instead, we thought of translating the entries before they are added to the backend so the cost would be lower. However, because we didn't get to building CMS, we actually had 1,500+ entries to translate, which we managed by building a web scraping script and using free google translate page ¯_(ツ)_/¯
Because of our very limited (non-existent) budget, we had to deploy the app to Heroku on the free plan, which means that if unused for 30 minutes, the page would "fall asleep" and the wake-up would take max. 15 seconds. No one has this much patience! We solved it in two ways:
- as soon as a person enters the main page, a "ping" is sent to Heroku to wake it up and the fetch begins;
- if the user enters the page on the endpoint that should display fetched data, we first show the 50 first records that are not fetched but hardcoded, and as soon as the fetch to heroku is done, it just adds the remaining thousand entries to the end of the list. It's not a perfect solution and if you have any better to offer, please share you insight!
I'm stating the obvious here but we needed to remember that whatever change we introduce, we need to check how it looks on all browsers, in different resolutions and on different orientations (horizontal/vertical). There are still a few bugs or parts that could be better but aren't there always?
When you work on a project you deeply care about, it is easy to put everything aside and just work yourself to sleep. That is not healthy. When planning for the project, include self-care time in your project timeline and downtime with your team because the more connected you are, the easier it is debug stuff together. We definitely were burned out after this project.
We received wireframes from a person who's not professional designer and so what looked good on a canvas-made picture looked not perfect in some browsers or dimensions. We made a mistake of not asking for wireframes for different dimensions/devices and also by just playing CSS by the ear (making a big simplification here). Because of that, it was so much more difficult to introduce major changes along the way. We unnecessarily spent a lot of time over stuff that could have been managed better had we defined a CSS stylebook beforehand. You code, you learn.
The page, although works okay and fulfills the wireframes we got, is not entirely satisfying for the NGO we worked with because any data they want to change needs to go through us or some other developer. It would have been much easier and more sustainable had we used Wordpress with React frontend from the get-go. However, initially, it didn't seem like there would be much changes as the project evolved over time.
Initially, we wanted to learn Tailwind, Contentful, localization, analytics, SEO and broaden our knowledge of Netlify, Heroku and Hooks. However, it's best to focus on one thing at a time, especially if you are a person prone to impostor syndrome (like myself). Don't try to challenge yourself on every step because that may turn out inefficient and paralyzing.