When you launch a new project there’s always a buzz of excitement, hope, relief, but also fear of failure and disappointment.
This is something I’ve experienced for all the projects I’ve been part of in the past 9 years, to the point that I’m actively looking forward to the first failed launch.
Nothing is more telling of the above then the feedback we’ve received from the users currently using our TranslatePress plugin.
Hope: We’re using your free plugin already. We would like to buy it later.
Fear of Failure: If it works with the plugin that handles the booking in our site.
Then there’s the abysmal number of active installs after sending over 7K emails to previous clients. Less then 10 for the first two weeks.
But this is not a story of something that looks like a failed product launch (more on that later).
Instead, I’m going to go back to December 2016 and start explaining almost everything we’ve gone through in the past 8 months for our TranslatePress launch, from initial concept to a brand new plugin that allows you to translate a WordPress website in more languages.
I’ll go through:
- why a new translation plugin and how we’ve come up with the idea
- allocating development resources and decide on a time-frame
- exceeding the time-frame by almost 2.5 times and the reasons for it
- coming up with a logo and something that resembles a brand fast
- deciding on how the plugin will be monetized
- implementing a brand new site, setting up payments and licenses
- beta launching the plugin and work on a new feature
Let’s Build a Plugin, They said! It will be fun they said!
As with every year end, we have a meeting with the rest of team over at Cozmoslabs about what worked in that year, what completely failed and things we’re looking forward in the next year.
My colleague Razvan Mocanu wanted to work on a brand new project. A new plugin. So we made a mental note, went on our Christmas holiday and came back in January with a single good idea we actually wanted to work on: a translation plugin for WordPress that anyone can use.
While this looks somewhat arbitrary, it’s not really:
- as plugin developers, we’ve had to deal with translation plugins since day one (right now we have support for WPML in all our plugins)
- before we switched to plugin development, we were a custom development agency that implemented WPML for various clients (it worked for us as developers, almost never for the end client)
- we really didn’t like the translation workflow of almost all translations plugins on the market. (Non visual, out of context, found in multiple places)
- we knew we didn’t want to do a WPML clone or work with a Multisite installations
So the only other existing plugin on the market that did something different was WeGlot. A Software as a Service implementation that offers automatic and manual translation. Basically the translation of your site gets loaded from their servers.
From the combination of the plugins and ideas above we came up with a concept similar to WeGlot, but quite different in its implementation:
Translate the Entire Page. No more switching between the editor, string translation interfaces or badly translated plugins. You can now translate the final page with full support for WooCommerce and site builders.
The main differences is in the implementation:
- support for dynamic strings ( gettext strings )
- everything stored locally, in your database ( you own your translations )
- a GPL plugin ( access to the codebase in case you need something different )
- a desire to make our plugin work with any WordPress plugin or theme and not the other way around, where developers need to add support for translation plugins
In January, my colleague Madalin Ungureanu stated on testing the core of the plugin, a PHP DOM parser class to see if we could work with it. It worked fairly good, we could do string search/replace from the database without slowing down the test site so we moved forward with starting the project. Razvan was to be the lead developer and he would be 100% in charge to deliver the alpha/beta versions at which point we would allocate more resources to the project. While not ideal, it was all we could do without hiring more people.
3 months. Let’s have an alpha/beta version in April. In July we started testing internally and pushed for a beta launch. July 31’st we made beta available for download. The final launch was September 4’th, more then 5 month over our estimate.
I’ve also come to expect software development tasks to take longer then expected
As with the slow launch, I’ve also come to expect software development tasks to take longer then expected.
There are some exceptions to the rule, but that is usually at the end of a development cycle, when the problem was already well defined and understood, didn’t require further research and all that remained was to write the code.
So why did it took longer then estimated?
- obviously we’ve underestimated the time needed. We really didn’t know how long it will take.
- the 3 months timeframe was forced more from practical reasons. Don’t push the project into the summer holiday season. (we did)
- Razvan is still a junior developer and this was his first big project at the company. While there were quite a lot of discussions regarding development direction and implementation, there was very little actual code written by anyone else from the team in the first stages of the project. So progress was slow.
- once I started testing the plugin in June, nothing worked. On my install anyway. While Razvan tried to generalize as much as possible the problem (fast string replace), it quickly become clear to us there were a lot more edge cases then we realized and budgeted for.
Logo Design on the Fast
While the plugin was being developed, I focused my attention on the design of a new logo and color scheme for our future website.
I’m by no means a graphic designer, but I’m ok pushing pixels around in Photoshop. I know my limits and I’m ok combining squares, rectangles and circles to come up with something ok. Not great, but ok. So I allocated a few hours and came up with 4 suggestions ( ranging from childish to ok-ish ) that I’ve shown the rest of the team.
We decided on the last one and moved forward with the site design.
All in all, there were probably 3-4 actual work days distributed over a few a couple of months to get all the graphics and design we needed for launch. The theme was a clone of the same custom theme we’ve used over at www.cozmoslabs.com so we’ve spent as little time as possible on getting this out.
While the design is really important, getting this out with minimum investment was more so. The Cozmoslabs design was a combination of 4 months of working with a designer (with a lot of back and forward) and another two months of implementing it in its entirety. We simply could not afford to do this at this stage. So we did something ok and moved forward.
We decided early on there will be Free and Pro versions. Our own previous experiences as well as that of other plugin developers in the WordPress community made it clear this was the way forward.
What wasn’t so clear is how we should differentiate the versions. Things we considered to be part of the Pro versions were:
- translation of custom post types;
- multiple languages;
- Google Translate API;
- SEO Module (slug, page title, and description translation).
- each pricing tear is for 1 year, with automatic renewal;
- the Pro versions only contain the Advanced Addons. So the free version will always be needed.
TranslatePress Launch – Brand new site, setting up payments and licenses
In order to sell our new plugin, we’ve tried to keep it as simple as possible so we used Easy Digital Downloads and Digital Licenses for EDD.
Unfortunately, for our setup to work we needed custom work:
- our payment gateway Avangate (custom coded because Avangate API is just weird)
- automatic renewals from Avangate (we can’t use EDD for this but something custom coded)
- digital licenses for a “Bundle” type of product so one license works on all Addons from the “Bundle” (this doesn’t work from EDD)
We wanted to use the All Access Pass Addon for EDD that solved the digital licenses for bundles, but that didn’t work for us because:
- if you have an All Access Pass, you can’t buy another, only increase the license period.
- it broke our automatic renewals that were custom (because of the way Avangate deals with automatic renewals)
- it also broke upgrades because again, upgrades are custom due to Avangate.
So we ended up custom coding an addon for EDD that sort of works like All Access Pass (the code is basically taken from the addon), but without the All Access part 🙂
Other than that, the Theme was recycled from Cozmoslabs as mentioned before and we used our own Profile Builder Pro plugin for the login/edit profile/password reset functionality.
One way of building momentum for a product is a beta launch. While there are other reasons for a beta launch (bug reporting), what I’ve experienced with other plugins in the past is that the main benefit is the possibility to talk about your product even if it doesn’t work yet. 🙂
While somewhat shallow in its pursuit, it’s just another marketing tool one can use. And as a bonus, we’ve also got a couple of proper bug/feature reports that made it clearer we were missing something critical with the beta version: there was no support for gettext fields.
Support for gettext fields was one of the big features we wanted to introduce AFTER launch. However, playing more and more with plugin and hearing what our beta users had to say about it, we bit the bullet and started working on this feature right after beta launching the plugin.
This is one of the biggest mistakes we could have done from a development point of view and one of the reasons why it took us so long to ship version 1.0. We delayed support for gettext because it was hard to implement.
A funny story about how we got started is that after the beta launch, we had a 1-hour power failure at the office. While I waited for the power to come back on, I started cleaning my keyboard. There was nothing better to do anyway, so I took a picture of the keyboard, removed all keycaps, and proceed to clean them one by one with a little bit of rubbing alcohol and a rag.
And for the next 2 hours, cleaned my keyboard and created a mental mindmap of the gettext implementation in WordPress, how our plugin was translating strings and how we could combine the two, without getting into performance issues further down the line.
After that, I had a quick discussion with Madalin about gettext, decided we should do it now, before version 1.0 launch and HE got to work on it.
There are a couple of takeaways from this story:
- it’s a bad idea to delay complicated features without a good reason. We knew it was going to be complicated, that’s why we delayed it for so long;
- while the 2 hours thinking about gettext did absolutely nothing in terms of actual development time (it took Madalin 1 month of work to get it working and he’s now in his second month dealing with wp_ajax and gettext), it was infinitely better than not thinking about it at all. It was what we needed to decide and get unstuck.
For promoting the beta we:
- wrote a beta article that’s also SEO optimized for “WordPress in More Languages” (no point in writing 2000+ words without hoping in the future for a bit of seo traffic.);
- sent a newsletter to our existing clients at Cozmoslabs about the new plugin;
- had proper “Signup for beta” forms on the TranslatePress website;
- two weeks into the beta we asked the 100 people who signed up for the beta for feedback (we used Mailchimp for this);
- for another two weeks, we ran Facebook ads that increased our beta testers to 160.
It took us a month of develop → test → fix cycles to get the gettext implementation working for strings rendered by PHP (normal page templates).
We still didn’t have gettext support for wp_ajax calls, but it was important to launch now and not later:
- if we would have delayed getting everything done, we would have lost time for marketing (or at least see what works and what doesn’t). If there is no product we can’t talk about the product;
- we could have lost the opportunity to sponsor WordCamp Bucharest that’s happening in October;
- once the website, payment gateway, licenses, support, and documentation are all set up, all we’re left with is working ON the product.
Ever since the beta launch, we started thinking about marketing the plugin.
A freemium business model means we’re dependent on a large number of free users and active installs.
With a new plugin that’s a lot harder than you might think, particularly with the new WordPress directory that takes into account active installs, reviews, number of responded questions on the forums, and other quantitative elements that we don’t have control over.
So our efforts were directed towards getting in front of as many WordPress admins as possible:
- we added cross-promotion in our other plugins (TranslatePress can translate our other plugins, so we’ve listed it in our recommended plugins section);
- added the free download to the account page of all our clients over at Cozmoslabs;
- got in touch with ThemeIsle to add TranslatePress to a recommended plugin list as it works great to translate their complex themes (we’re using Hestia for our demo site);
- sponsoring WordCamp Bucharest and getting to talk to potential users face to face.
All this effort is particularly important at the beginning to get a bit of traction so TranslatePress appears in the WordPress.org search results.
We tried to be as less spammy as possible, if that’s even a thing. We didn’t use notices that appear on all backend pages or send newsletter after newsletter to our existing clients ( just two for beta and Version 1.0 launch).
Future marketing plans:
- we plan to create tutorials for a lot of popular themes and how to translate them (thanks Ionut);
- continue our outreach efforts towards plugin and theme developers. We want to add support for plugins, not for plugins to have to add support for us;
- content marketing for multilingual is hard because we won’t rank high in search engines. Not at first anyway. So while we’ll be active on this front, it’s not highly important for us now.
Conclusions from our TranslatePress launch
The main thing I want to highlight about this 8 month process, is that it’s not the end of the line. Lack of interest at the beginning is normal. Little to no downloads are normal. Little to no feedback is normal.
Instead of worrying about all this, I’ve come to see initial launches for what they really are: structure on which the company can build the product and market it in the future.
The real success or failure comes at a much later time.
It’s even been comical for me to see how bad initial launches are and to make bets with the rest of the team that are almost always way more optimistic 🙂
Finally, here’s a list of the things we’ve learned about our TranslatePress launch in this past 8 months:
- launches as building up the structure of the project. Once out you can work on marketing and improving the product;
- don’t delay thinking about complicated parts of the project. You can choose to include them or not in Version 1.0, but never, ever NOT think about them;
- ask feedback from other people from the community. I’ve had some really interesting discussions with the PostStatus community (technical), with local WordPress people who implement multilingual websites (about features), with actual users (they loved the easy-to-use interface, if only the plugin worked for all strings 🙂 ), with other WordPress product people (marketing). Future features, technical decisions, and marketing are influenced by this feedback;
- spend the needed amount of time on important features. We’ve spent a lot of time on the gettext implementation and continue to do so. It’s the one thing that makes the entire plugin so versatile, so it has to work;
- unless you’re selling actual design work, don’t spend a lot of time on the website design. Focus instead on making the content clear, without fancy words, and structured so it’s not overly complicated for someone non-technical. If you’re not sure where to start, just go over to AffiliateWP and steal their content structure. No one will notice;
- everything you can set up and forget should be done early on. If you can’t use off-the-shelf tools to sell your plugin, custom code them now if you know how to. With the infrastructure in place, we can 100% focus on the plugin for the next year or more, without worrying about changing the pricing structure, renewals, accounts, etc.
So this is the beginning of our TranslatePress adventure.
If you managed to read all of this, thank you for your time! And try TranslatePress, even if it’s just to play with it. It’s cool like that!
[NOTE]: This article about the TranslatePress launch was Originally published in the PostStatus newsletter.