When it comes to selling digital products online, having a live demo to show off your product is extremely important. No matter wether you’re selling WordPress themes, self-hosted web applications or SaaS products, having the ability to show your potential customers what your product can do should always be an essential part of your marketing efforts.
When it comes to setting up your live demo, there are several ways to skin a monkey. The most basic method is simply putting a copy of your product online and give everyone who ends up on your sales site access to this copy. Now, this being the most utilised method (due to it’s simplicity), there are some major drawbacks to this type of live demo:
- one user changing data will affect the way the demo looks for other users
- in the case of a web application where all uses access the demo using the same user account, this create obvious issues when several users access data within your application at the same time
- you have no way to control how your demo looks as time goes by since many visitors will make changes
A solution often applied is restricting access and functionality in the demo, which works kinda ok. The downside of this approach is that:
- users won’t be able to experience the full functionality of your application or theme
- updates are pain, as every time you update your application or theme, you will need to re-apply the same restrictions to make sure users don’t stuff up the live demo.
Until recently, I myself have used the “restricted access” methods for the live demos of my products. I did this in combination with a cron job running every half an hour or so to reset the entire demo. The cron job would call a PHP script which would delete the entire database and re-imports a SQL file essentially resetting the live demo to it’s original state. The approach has worked well for my first 5 products. However, with our latest product (SiteCloner) we ran into major issues using the approach. Since SiteCloner is a web application using a single user login (and so all the demo users accessed the application with the same login), we quickly noticed all sorts of issues where one user was stuff up clones created by another user.
It quickly became clear this approach was not working well for this product so I quickly had to come up with a different solution. I decided to put together a system using multiple live demos rather then a single one. And I wanted to make sure then only one single user accesses a single demo at any given time, so I’d never have to worry about multiple users in a single demo stuffing up each others experiences. Furthermore, I wanted to make sure each live demo can only be used for one hour maximum.
Step 1: creating the actual demos
I started off by deciding how many demos I would need. Now, this will depend heavily on how popular your product is, how many visitors you’re getting, etc. So you would have to have some data about your users before making this decision. I simply looked at my analytics data (gathered from Zopim) to determine how many people were looking at my demo per hour. At that moment, SiteCloner was getting about 25-30 uniques per hour, so I figured having 50 demos would be sufficient (better to have too many then too little!). For my demos, I decided to go with subdomains, using the format “demo1.sitecloner.net”, “demo2.sitecloner.net”, etc. Wether you use subdomains or subfolders is arbitrary and entirely up to you. After creating all the subdomains in cPanel, I proceeded to upload all the demo files and create all the databases (hint: if you have access to cPanel, you can save a lot of time by creating a local ZIP of your files, uploading that ZIP to your server via FTP and then use the cPanel File Manager to unzip the archive).
Step 2: create the demo database
Next, you will need to create an additional database to keep track of your demos. Since we want to have each demo run for 1 hour max, we’ll need this database to track which demos are active and how long they have been active for. Furthermore, since we only allow users to access a live demo for 1 hour max, we will want to reset the user password for each demo as well after the hour finishes. In order to keep track of the passwords, we will store the current passwords in plain text in this database as well. Now, normally, storing passwords as plain text is extremely insecure and basically a bad idea, however since we’re not storing anything valuable inside the live demos and the passwords are reset every hour, in this case I don’t have a problem storing those passwords as plain text. The reason we’re storing the passwords at all, is that we’ll need to provide the user with the password so he or she can access the demo. Below, you’ll see a screenshot of how the table looks:
We’re storing the URL so that we can provide the users with the URL to their personal private live demo. The “dir” and “database” columns are used by the reset script (which we’ll cover in the next section). The “active_since” column contains a time stamp to track when the demo was activated and the “active” columns tracks which demos are currently active (1 for active, 0 for not active).
Step 3: the cron job and the reset script
In this step, we will want to create a script which is called at regular intervals using a cron job. For the SiteCloner demos, I have configured the cron job to run every 5 minutes. I found the 5 minute interval to work well, as having it run very often, like every minute, will put a larger strain on the server and having it run less often will mean that demos can run longer then the allowed 1 hour. I have chosen to place the reset script on yet another subdomain, however basically this script can site wherever you’d like. We will need this script to do the following:
- access the table from Step 2 and retrieve all demos that are marked as active and which have been for at least one hour (compare the current timestamp to the timestamp from the table and if there difference is more then 1 hour, grab the demo)
- for all these demos; reset the demo, reset the password (using a randomly generated string), set the timestamp to 0 and set “active” to 0
Now, as far as resetting an individual demo goes; the exact operations will depend heavily on the nature of your application of WordPress theme. If you product only allows for manipulation of database data, then a simple database reset will be enough (I do this by deleting the current tables, and re-importing the SQL from a SQL file containing the original demo data). For this to work, you will want to make sure your reset script is located on the same server and you have access to each demo’s MySQL database. For SiteCloner, every database has the same password and we store the database name in the table from step 2, this gives me what I need to access each MySQL database and reset the tables. Now, if your demoing a (fully functional) WordPress theme or application which has access to the file system (for uploading images for example), you will want to make sure you delete uploaded images as well.
Step 4: provide the user with the demo link
The last piece of the puzzle. We will need a way to provide the user with the demo URL and access info (if needed) when they request to see a live demo. The way I did this for SiteCloner is by having a “Live Demo” button on the sales site. This button is linked to another script and when called, this script will query the table from step 2 and fetch the first available (with “active” is 0) demo from this table. The script will then set the timestamp for this demo and changes the “active” status to 1. Finally, it will redirect the user to the live demo URL (with the username and password as part of the URL) and the user can now access the demo for the next hour.
The major drawback is of course that we have 50 live demos, rather then a single one. Now, I am not saying every single product will need those 50 demos. For many products out there, a lot less will probably still be enough. But even with say 20 demos, implementing updates for example will take some additional time. I did consider this and found the fact that I can now provide every single user with a private and fully functional demo outweigh the additional work when implementing updates. When the time to update comes, I will probably figure out an easy way to push updates to all live demos in one go.