What I planned to do and what I did
■ Publish this page on kiru.io ■ Get domain flashdictation.com ■ Add progress bar in days on the main page ■ Setup project on GitHub ■ Setup initial landing page with a simple description ■ Make a simple logo □ Define MVP (Minimal Viable Product) □ Define timeline ■ Publish on Twitter
How did the day go?
I registered the domain via Cloudflare. The webpage is a simple Next.js static page (for now) deployed via Cloudflare Pages. Why? Because it was the fastest way for me to get started.
Cloudflare Pages deployment did not go smoothly. I ended up having the following error:
19:21:05.595 export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH" 19:21:05.595 [0m 19:21:05.938 [32m> Successfully installed Yarn 1.22.4! Please open another terminal where the `yarn` command will now be available.[0m 19:21:06.302 Installing NPM modules using Yarn version 1.22.4 19:21:06.745 yarn install v1.22.4 19:21:06.836 [1/4] Resolving packages... 19:21:07.046 [2/4] Fetching packages... 19:21:19.165 error email@example.com: The engine "node" is incompatible with this module. Expected version ">=12.22.0". Got "12.18.0" 19:21:19.177 error Found incompatible module. 19:21:19.178 info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command. 19:21:19.199 Error during Yarn install 19:21:19.202 Failed: build command exited with code: 1
It turned out, without any config, CloudFlare uses node version 12.18.0. To fix this I had to set the following environment variable:
Once that was done, everything went as expected.
For the logo, I used Hatchful by Shopify. I did not define the MVP (Minimal Viable Product) yet, since the idea was not clear to me as well. So I spent most of the time writing down what I expect, and what problem it should solve.
Go checkout what I produced today:
Is it possible to bootstrap a successful SaaS business in 24 days? Let’s find it out together: AdventOfSaaS 2021!
My name is Kiru. Join me on the journey of this project. I will keep this page up-to-date with daily progress and any interesting stats.
You probably know AdventOfCode, where you solve a different puzzle every day. Similarly, I work on a SaaS (Software as a Service) project every day. The time spent varies depending on my workload. This project is done alongside my usual work. From 1.12.2021 to 25.12.2021, I pledge to dedicate at least 1h per day (with 4h weekend budget) and post daily updates here.
This launch post was written before December, as well as the project ideas were collected. No code has been written until now.
Dictatly: I am trying to improve my French. One effective tool is dictation. I would like to watch a video or listen to a podcast and write down what I hear. Right now, I do this by hand and then go over the text to correct it. It would be simpler to use the existing transcript to autocorrect and show the mistakes, as well as track my mistakes.
Few notes on the idea:
The first step is to create a landing page, which will contain more information.
These are the milestones I set to rank the project success in the end:
If something is not clear, or you just want to contact me, go ahead. Hit me on Twitter (kiru_io).
The main goal of today is to define the MVP, e.g. more in detail and the tiny steps needed to go there.
The detailed tasks help me to stay focused, and not get distracted by other (nice to have) features.
For the audio, I need a way to show a player on my page. I will try with this component: react-component. It seems easy to use and allows audio and video - so I don’t have to implement it by myself.
For testing, I will use the innerFrench video - especially since they come with proper subtitles, and the transcripts are free.
Today’s goal was to experiment with the video player. It was fairly easy to add the player, most of the time I spent making the page prettier.
The final result is:
Tomorrow, I am going to add the correction logic. That should be enough to test the MVP. The next step is to add a few shortcuts to control the player.
With the above mockup, I can easily explain this project to anyone.
I managed to complete the simplest MVP:
Today I focused on implementing the correction part. Initially, I spent some time coming up with a simple algorithm but wasted too much time. I ended up using a diff-library (well I didn’t think “correction” in terms of “diffing”, I was trying to find miss-matched words, which in the end is “diffing” duh!)
This is the result:
There are a few changes I will make:
Started with updating the todos on FlashDictation.com. Apart from that, added a shortcut for the video-player (Key 1) for starting and stopping. That makes it easier to type what I hear without having to move my cursor and hit the Play/Pause button.
This completes (imho) all the features needed to use the tool. Until now I hardcoded the transcript and the video. Optimally, I would like the user to enter a YouTube link and play the video. Getting the captions via YouTube API seems possible.
I spent most of today figuring out how easy it is to integrate the API. It seems doable, but I wanted to avoid adding an external dependency.
There are a few alternatives:
Limited set of audio+transcripts The alternative to YouTube links is, that I collect audio+transcripts (free to use) and allow only pre-selected ones.
While researching, I learned about the
podcast:transcript tag for RSS feeds, which points to the transcript.
<podcast:transcript url=“https://host.com/1.srt" type=“application/srt” />
This seems a great way to get the transcripts of the audio.
I don’t have a proper idea what is the best solution. A very simple approach is to provide some audio+transcripts.
Later on, I can still replace them by something more dynamic.
My initial idea was to create an app like this:
After trying to figure out the best way to integrate the YouTube-API (I wasted already ½-hour to figure out why the API-credentials were wrong.), I decided to give up for now (not because it’s hard, just because it’s too much effort for an MVP) and go further with a predefined set of dictations.
For english dictations, I will stick to these freely available short stories, and use the videos from YouTube. Later on, I have to find other resources for different languages (maybe ask on r/languagelearning ?).
For tomorrow these are the plans:
Today marks one week I have been working every day for at least 1 hour. At the beginning, I made huge progress, got the PoC implemented very fast, and deployed it to flashdictation.com. Now I have something working, but I need some goals for the next two weeks.
This project is called AdventOfSaaS - so where is the SaaS part? That is something I have been thinking about the last two days. How to monetize this project? What I have now is a web app to practice dictation. It is not perfect, does not work for anyone - but solved my problem. I could even extend it, such that I can paste the link to a video and enter the transcripts and create a “dictation” page for that video. That way, the user can share that link. Once you land on the page, you can see the video and an input area to type what you hear. Once done, let me correct your mistakes - as for now.
So how to monetize? One way is to charge to create the “dictation” page and target teachers. As a teacher, you can create a dictation page and send it to your students. They can listen to the audio once - and type what they hear, and send it back to you. You can use the “auto-correction” tool to see what mistakes they made, and send it back to them
For the above use case, I need to change Flashdictation as follows:
Deadline: 7 days! By 14th I want the MVP (with the above features) to be done.
Today I worked on redesigning the landing page. This is how it looks like now:
This is how it looks like now. It is not done yet, but almost:
I need to add some infographics and explain what is going on. The page should be optimized for mobile as well. Today I only focused on the desktop version. Tomorrow, I will fix the audio-player (it should auto-play and show somehow it is muted), and test it on mobile.
The written text should also be synchronized with the audio. I need to add a “correct me” button. Once that is done, I can write down the final features.
I am pretty happy with today’s progress. 💪
Continued on the landing page. Replaced the blue buttons with actual text and a logo, so it’s more clear what each part stands for.
I need to add more text to describe further in details, what every part is.
I don’t like if you end up on a landing page, and you don’t understand what the project is about. Nowadays, the focus is on fancy design and less text. But I don’t see why we can’t have both.
Anyways, this is the result after today’s work.
I also added Plausible.io to track how many people are using the page. Let’s see tomorrow how many people visited the page.
Note to me: Add Plausible.io from the beginning next time!
Added navigation to the page, visually this does not change much:
Behind the scene, I had to re-organize the code. The current online version is broken, since I host the page via Cloudflare (they only support static next.js builds).
Next, (haha) I have to move away from Cloudflare. Maybe try Vercel or build on a VPS?
I moved away from Cloudflare Static pages to Vercel. Until now, I only had static content, and no server-rendered part. That might change, so I move rather now than later.
There are not many visible changes today, but I reorganized the code, and started adding the login components. It takes more than a few hours to finish that, so I decide not to deploy the half-broken parts. I will complete it tomorrow and push a version.
A few days ago, I wrote a mail to innerfrench ( A French podcast, targeted at beginners. ), and got a replay:
This is great news! Next, I need to find some good English examples!
I have a working authentication system! Initially I wanted to add NextAuth.js and Google authenticator. That approach needs a hosted database instance (to store dictations + text). In the end, I decided to try out Supabase. why?
I found this nice project from Vercel, with Stripe and Supabase integration. Took it as a template and adapted it for my use case. This is the current result:
The UI looks ugly - since I had to adapt some css, and did not spend much time to make it prettier. What counts is, that I can login and create an account. I will focus on having all features done and then spend one or two days on makeup.
For now, you can create an account and login. Be aware, I will wipe the database before I publish it on ProductHunt (or anywhere).
Tomorrow, I should work on the following tasks
From yesterday’s plan:
Those are implemented. Now I can add new dictations, and see them. It took me some time to grasp the Supabase Row-level Security feature, but once I understood it, the implementation was straightforward.
The form looks ugly (as usual), I did not spend much time making it better:
The login and creating dictation workflow works as expected. I should add some checks (e.g. empty values and so on), but for now, I have something working:
For tomorrow, I will focus on the following two items:
Let’s begin with the simplest change: Added a WIP based on this blog post:
Implemented the actual dictation page. The user can type what he hears and see a score. For the score, right now I use the Levenshtein distance (for non-programmers: An algorithm which gives you how close two words are). It is not the best score, but I get a single value for free. I have to brainstorm more about what is a good metric.
The workflow looks like this:
You can still not login in to production. I have to setup a proper production environment in Supabase, because the URL which is sent in the mail (for the magic-link) is hard-coded. I tried to fix it in a few minutes, but it will take longer than that. I decide to postpone it until all features are complete.
For tomorrow, I will spend some time to make all the ui-components consistent, and test on mobile.
I got asked where is the link to flashdictation.com a few times, so added a prominent link on the top of this page (with the logo).
Before I changed all pages to be consistent, I re-evaluated the todos, and reorganized them:
This is the result after re-doing the dictation pages:
The landing page is not completed yet, as well as the login and the actual dictation page (which you share). I did not have much time to finish those today.
The goal for tomorrow is to make the login and dictation page consistent with the above pages.
I will update flashdictation.com once all of those pages are complete.
As planned, I finished the redesign of the login and dictation pages:
I did not manage to fix the production environment, since there are still some database changes missing. Hopefully should be done by tomorrow.
No UI changes today. I tried to fix the production environment, but there were too many issues. The main problem is, that I have to setup a different Supabase project and copy all data. Unfortunately, that is not easy. So I decided to re-do the database and recreate the data. Most of them being Stripe-products. Then I spent some time fixing stripe production.
Obviously, this did not work as flawlessly. Finally, I gave up and thought I can at least fix Vercel to have the landing page fixed. After ignoring a bunch of TypeScript errors, I have a new version online:
Managed to fix the production environment (by copying all data from dev to production). But be aware, I will wipe the database before I put the project on ProductHunt.
I am preparing to add Stripe integration. A warning is shown once you hit 5 dictations:
There are not many changes, and my time to work alongside is limited. Therefore, I will focus now on completing a “SaaS” project, then having all the features. Once the project is online and I have a few users using them, I can still add new features.
These are the missing steps:
The goal should be to invest next week in marketing (aka promoting the project on different platforms). Wish me luck.
Today was the longest I worked on this project at once. I wanted to finish almost all tasks which needed to be done before going live. I don’t know where to start, there were too many changes. Among the major tasks done are these:
Added pricing to the landing page:
Added Stripe integration:
This was something I have been postponing for a while. Just out of fear it would take longer than I expected. In the end it did! I spent too much time debugging a stripe-api call issue, but eventually managed to fix everything. There is still a tiny bug left on production - but I don’t know exactly how to fix that. Once I create a subscription, Stripe forwards me to a page, but that page contains the Vercel URL - instead of flashdictation.com (for now that is not a huge issue, I will focus on marketing and fix it later).
Once you click on subscription, you will be forwarded to Stripe, where you can provide your payment information:
Some tiny tasks
Next week, I will focus on promoting the project. Finding some customers, and fixing any major bugs.
Today I distributed the project link to a few friends, and got some feedback back. All of them are techies though and not my real target audience. I noted the feedback, but will wait to see what actual users say.
The current project which is online, is usable, but I have to dogfeed it a bit. For the rest of the week, I will focus on putting the project on various platforms.
This is my plan for the last few days:
Today I took the day off.
Also published the project on Supabase and IndieHackers.com as product.
I forgot that the plan from yesterday (20.12.2021) does not contain postings the project on HackerNews. Here we go: Show HN: Dictations for Teachers Made Easier .
Same on IndieHackers. I put the project online: Flashdictation, but waiting for approval.
I wanted to create a short video - but I am not very skilled in editing videos. I tried to use veed.io, but it was too cumbersome (just for me, took me too much time). I decide to try Remotion. It was on my bucket list for a long time, but never found time. This was the motivation I needed to try it out.
The library was surprisingly easy to use. It makes editing videos as fun as programming. I still struggle to wrap around the concepts (e.g. Sequence / Composition / Still ), but it’s quite fun to debug a “video”.
Anyways, here is the video I tweeted:
👋👋— Kiru (@kiru_io) December 23, 2021
Checkout my latest project: https://t.co/8dPSscYr1v ! 🚀🚀
A dicatation tool for teachers and language learner🤓! Just the beginning - more feature will come!
Developed in 23 days. Documented on https://t.co/OcGcC0jxjZ 💪
btw, RT is very much appreciated 🙏 pic.twitter.com/DTNlM9pjQZ
Many people in my bubble (aka Twitter, and the news I read) see ProductHunt (PH) launch as the holy grail. Therefore I waited a while to put it on ProductHunt:
Tbh, choosing the 24th of December to launch the project on PH was not my wisest move. On the other hand, my target audience is not on ProductHunt. I just hope it will help to rank the page a bit higher on Google (aka generate some backlinks).
Apart from that, I re-read everything I wrote until now and corrected some mistakes. You can see the diff here.
For the next time, a few lessons I already learned regarding writing:
Today marks the 25th and last day of this project. It has been an interesting journey so far. This journal entry will be longer than usual. I will cover the following topics
From the beginning I tracked every minute I spent on this project. The idea is to know how much this project costs me and what the break-even point is. I will keep tracking the hours and once I have some income, I will post more about that.
In total, I spend 61h and 38min on the project. The following graphics show the hours spend by week and by the hour (the axis are hidden by intention)
Most of my work was done after work, and in the third week I spend a weekend to finish almost all features which were left. It was not planned, but in the last week I did not have much time to work alongside my job - so I decide to do a sprint and spend less time in the last week.
The following charts shows the number of visitors from Plausible.io:
I made the mistake to include on day9. With 118 unique visitors, I don’t have many - but nevertheless more than 1 (which is me). Considering that many block tracking, 118 not blocked visitors is not bad. I am quite happy with that.
Another of my goals was to attract more Twitter followers:
I consider this a success. I gained 6 new followers and 1315 people visited my profile.
What I achieved
At the beginning I defined some levels on how to evaluate this project. I reached Level 0 and Level 1 (at least 5 new Twitter followers and one paying customer). I don’t have any paying customers except myself (yes I subscribed and pay for my own SaaS, it’s called eat your own dog food). Apart from the defined goals, my main success is definitely having something online, even this blog entry is a success in my eyes. This project, despite having no actual users shows to me how much can be done by just being consistent, and keeps me motivated.
Here are some lessons I learned. Which are mostly for me to improve for the next time.
This is not going to be my last piece about Flash dictation. I will continue developing it, especially adding more features. I will not post any daily update, since I think the frequency is too high (especially on Twitter, I will experiment with weekly updates). The goal is still to attract an actual user. Despite having no user, I will keep using it to learn French. I have more plans to market it to language learners. This is just the beginning.
Thank you everyone for supporting me!