Make Your Site Mobile-Friendly in Two Minutes

After checking out B. Adam Howell’s excellent IYHY.com site a couple of weeks ago, I thought it might be a good idea to write a little tutorial about how to make your entire site more mobile-friendly without even touching your pages. You may think that since you write valid code and separate structure from presentation at all times, your site already works great on mobile devices. You may also think bad things don’t happen to good people. In both cases, you’d be wrong.

The fact of the matter is that the state of HTML rendering in the wireless world is all over the map right now. Some browsers, like Pocket Internet Explorer, are actually pretty good at parsing through standard web pages. Others can scarcely handle layout rules at all. And still worse are the mobile browsers that load all CSS and javascript files, attempt to use them, and screw up the experience even more in the process.

What’s really needed until HTML/CSS/JS support is improved in mobile devices is a little server-side filtering. By pulling out everything a mobile device can possibly choke on before it even gets to the mobile device, we can create a mobile version of our site which is not only viewable on more devices but is much quicker to download as well.

And you know what? The mobile version of your site is probably going to be much easier on screenreaders too.

Four easy steps

Outlined below are the four steps to get this done in a matter of minutes, provided you are in an Apache environment and can run PHP. If you’re not, these steps can easily be adaptable to other technologies.

Step 1: Set up a domain mirror

If your site lives at www.myawesomeblog.com, you’re going to want to set up a subdomain at mobile.myawesomeblog.com. How you accomplish this is usually pretty straightforward but differs depending on your host. I use Dreamhost and from their control panel, I can add subdomains effortlessly until I pass out from excitement. You want to set up your subdomain as a “mirror” of your main site, meaning the subdomain is really just pointing to your existing site.

Step 2: Create global_prepend file

The next thing we’re going to do is a create a PHP file which will be automatically prepended to every page of our site. Call this file something like "global_prepend.php" and throw it at the root of your server:

This code uses a PHP function called ob_start() to read in your entire HTML source, run some rules on it, and then send the output to users’ web browsers… all in real time. The first "if" statement simply checks to see if the user is coming from our special “mobile” URL, and if so, runs seven replace statements on the code. Here’s what each line does:

  1. Changes all URLs to “mobile”-ized URLs.
  2. Strips all linefeeds, carriage returns, and tabs.
  3. Trims multiple spaces down to one (HTML doesn’t recognize more than one space in a row).
  4. Changes any anchored images with alt text to plain text anchors.
  5. Strips all stylesheets, images, inline styles, scripts, and comments (including RDF).
  6. Tells search engine robots not to index or crawl the mobile version of the site so as to not create duplicate listings.

Step 3: Create global_append file

Next, we need to create a tiny PHP file which will automatically get added to the end of every file on our site. This is the code that actually outputs the page to the browser. So the flow is like so: Suck code into buffer, siphon fat away, spit contents of buffer into browser.

The code for the global_append file is below. Call it something like "global_append.php" and throw it at the root of your server:

Step 4: Enable prepends and appends using .htaccess

If you don’t already have an .htaccess file at the root of your server, open up a new text file and add these lines to it:

php_value auto_prepend_file /localfilepath/global_prepend.php
php_value auto_append_file /localfilepath/global_append.php

Then save it to the root of your server with the filename ".htaccess". If you already have an .htaccess file, just add the above lines to it.

* Important Note: If you copy these two lines from your web browser, you might need to delete the carriage return and make your own. Sometimes a browser’s carriage return will cause your .htaccess file to fail (you’ll know immediately if it has failed because your site won’t come up).

Assuming your subdomain is live, you should now be able to hit your site in a web browser using the special mobile URL and see a nice, compact, imageless, styleless, scriptless version of your site. Voila!

Here is what Mike Industries Mobile looks like.

A look at the results

Let’s look at some before and after shots of Mike Industries and a few other notable sites when taken “under the knife” (screenshots are from a Treo 600):

Mike Industries


Size: 72k
Time to render: 33 seconds

Size: 26.1k
Time to render: 5 seconds

Mezzoblue


Size: 31k
Time to render: 22 seconds

Size: 8.3k
Time to render: 5 seconds

Stopdesign


Size: 68k
Time to render: 28 seconds

Size: 15.7k
Time to render: 5 seconds

Zeldman


Size: 29.8k
Time to render: 17 seconds

Size: 25.3k
Time to render: 13 seconds

Shaun Inman


Size: 101k
Time to render: 39 seconds

Size: 18.9k
Time to render: 5 seconds

Joe Clark


Size: 97.1k
Time to render: 23 seconds

Size: 58k
Time to render: 7 seconds

Gizmodo


Size: 177.6k
Time to render: 62 seconds

Size: 46.2k
Time to render: 7 seconds

The figures above illustrate both speed and compatibility improvements in all cases and this is with image loading turned off on my device. Flip image rendering back to its default setting of “on” and the improvements are staggering.

It’s important to note that the tests above do not point to any coding problems or inefficiencies on the part of the site authors (except for mine, which is just a big pile of crap). The fact that sites above average about 30 seconds to even begin rendering is more a function of the speed of cellular networks and the inability of some mobile devices to efficiently display content. Since we can’t change either of those things, we do what we can in the meantime, and that’s what this is all about.

Notes and thoughts moving forward

  • I openly invite anyone reading this article to suggest improvements to my replace statements in the ob_start() code. The Wolf has spit milk through his nose checking my regular expressions in the past, but with his help and the help of the best tutorial in the world, the regexes are pretty tight now. If you have any modifications or additions, post them in the comments and I’ll merge them in if appropriate.
  • Using ob_start() requires PHP to parse through your pages, thus creating additional server load. Dreamhost lets me test CPU load and I don’t notice any problems or performance degradation, but if you’re hosting on a Commodore 64 or in an extremely high traffic environment, just make sure everything is still humming along after you’re all set up.
  • In order to use auto prepending and auto appending, you must be running PHP as a standard Apache module and not “as cgi”. If need be, you can run PHP as Apache sometimes and CGI other times by using your .htaccess file to specify rules.
  • I specifically left out much mention of accessibility in this article because each site and each screenreader are different, but you can begin to see how radically we can simplify pages on the server-side to improve such things. In the world of accessibility, simpler is almost always better. It’s the reason why Joe Clark’s name is only two syllables.
  • Finally, there are all sorts of ways to expose your “lite” version to users. I will probably simply add a “lite” theme have added a “Mobile Version” link to my selection of themes in the sidebar, but you could just as easily write a snippet of javascript to automatically send people with screen resolutions of less than 640×480 or certain known wireless user agents to your lite site.
  • Note to Dreamhost users: Dreamhost runs PHP as CGI by default. To switch it over so it runs as an Apache module, just go to “Domains > Manage > Edit” in the control panel. Then, uncheck the “run PHP as CGI” box. Also, if you have HTML pages on your site that aren’t PHP, you can force them through the PHP interpreter by adding this line to your .htaccess file: AddType application/x-httpd-php .html .htm
Like this entry? You can follow me on Twitter here, subscribe via email here, or get the RSS feed if that's how you roll.

291 Responses:

  1. raph says:

    Would love to see this good-Mike fix work with the latest smartphones. I have a website with many pages. Made all the necessary changes including the .hta access file. I get no errors and the sub-domain points correctly. But I get no changes to the site. It’s as if the script is not there. Any suggestions what to look for?

  2. raph says:

    I just realized that Mike had answered an earlier poster by saying if she had static html pages, this script wouldn’t work. My site is all html, no php. Could that be why I see no change in the sizing and display?

  3. easiest to test by creating a blank html or php page for testing purposes – blank page with no other variables involved. php hosting version?

  4. satuiku says:

    thank you for information…
    how to make my blogger mobile friendly..

  5. The Aprentice says:

    Is there anyway to implment Mikes methods in a free website publisher and host company such as google sites?

  6. Hi,
    We just tried this on our website after fully following the directions and when I try to use the global append and prepend directives in php.ini, I get
    fatal errors on the website.

    Has anyone else had this?
    Regards,
    Rob

  7. Elliot Khazon says:

    Great post, Mikel. Actually if you have unusuall line feeds (\n\t) it is not captured by the line feed expression. You can update to [\n\r\t]+|(\r\n)+/
    Thank you!

  8. Elliot Khazon says:

    (\n\t) …. (\r\n)

  9. Hi Elliot – do you think that would be the cause of my issue?:
    “We just tried this on our website after fully following the directions and when I try to use the global append and prepend directives in php.ini, I get
    fatal errors on the website.”

    Regards,
    Rob

  10. Bump for any help with this

  11. Elliot Khazon says:

    Robert -I don’t think that’s your problem. That reg exp would not cause fatal errors.

  12. Thanks Elliot.
    Why would this procedure cause fatal errors? Would you know what would cause those type of specific errors?

    Regards,
    Rob

  13. Elliot Khazon says:

    What message do you get or do you get one? If not – consider looking at the logs…

  14. It’s a strange File not included error when trying to include the global appends and prepends. It appears we cannot set a path for these files via php.ini

  15. Elliot Khazon says:

    Look here:
    http://www.php.net/manual/en/ini.core.php#ini.include-path

    Is it in php includes directory?

  16. Hi Elliot – Yes, had it in that directory and had it all working. The global_prepend messes up the sessions that are required for using the members admin section.

    Any other suggestions/workarounds?

    Regards,
    Rob

  17. Hi Elliot – any ideas re: this?
    I’m at a loss

    Regards,
    Rob

  18. Elliot Khazon says:

    I am confused when you say :”Yes, had it in that directory and had it all working.”
    May be the sessions that require admin access should not use this…

  19. Thanks Elliot…Well, the thing is that with a global prepend, I cannot see any way to exclude files….?

    Regards,
    Rob

  20. Hi Elliot,
    Sorry for my late reply, but I needed to delve into this. Basically, it looks like as long as you have to use sessions, this will not work as you cannot pick and choose which files to want appended and prepended. It is a php.ini setting that applies to all files on the server.

    What are your thoughts on this?

    Regards,
    Rob

  21. Hi Elliot,
    What were your thoughts on the above findings?

    Regards,
    Rob

  22. Can anyone please help?
    Basically, it looks like as long as you have to use sessions, this will not work as you cannot pick and choose which files to want appended and prepended. It is a php.ini setting that applies to all files on the server.

    What are your thoughts on this?

    Regards,
    Rob

  23. Can anyone help with this?
    Elliot or anyone who can suggest?

    Regards,
    Rob

  24. Mike D. says:

    Robert: I suggest you post your question to some place like stackoverflow.com. This isn’t really a tech support forum. Thanks…

  25. Mike, Thanks for this shortcut way to make website mobile friendly, however, I’ve only 1 doubt that this post is approx. 5 yrs. old. Will this technique work now-a-days?

    If yes then I’m going to define it…

  26. Will this hack work with Joomla?

  27. Hi Mike(?),
    In your script, is there anything I need to do to replace [‘SERVER_NAME’] with my server (GoDaddy.com), like I of course have to replace mobile.myawesomeblog.com with mobile.golfntours.com?
    Many thanks

  28. Hi Sir,
    I uploaded files as recommended but my site became inaccessible on my laptop – ‘Error Alert’, so I had to quickly put everything back as before.

    Note: Other than the subdomain of mobile, we already have several subdomains within our directory; does it interfere?

    Many thanks

  29. Alex says:

    When trying to use the .htaccess file I get this error:

    [Thu Sep 23 16:24:05 2010][alert] [client 68.64.217.2] /data/20/1/2/81/1980896/user/2164097/htdocs/.htaccess: Invalid command ‘php_value’, perhaps misspelled or defined by a module not included in the server configuration, referer: http://mobile.lohicannabisclub.com/

    What is the problem?

  30. Will says:

    Here is an easy solution that works, never got Mike’s to work. http://wilcoads.com/?p=143 works! But the link I am posting does although you will have to create some mobile pages for your site. BTW I tried his several times several years ago…

  31. Robert Eisenstein says:

    Will – nice post !!
    Do you also have a process like that for Blogger Blogs…and Websites in general?

    Regards,
    Rob

  32. Ok, I have been trying for two days to get this right. Maybe this will help some that are getting the 500 server error.

    If you are getting the 500 server error place the following into your .htaccess file:

    suPHP_ConfigPath /home/usr/php.ini

    order allow,deny
    deny from all

    Then in your ROOT Directory NOT the public_html create a file name it php.ini then place the two php_values in it.

    php_value auto_prepend_file /home/usr/public_html/global_prepend.php
    php_value auto_append_file /home/usr/public_html/global_append.php

    Replace the /usr/ with your sites user name.

    At least I thought that would do it, but when I do the emulators they return a 502 (invalid gateway error) So something else must indeed be wrong.
    I tried both SERVER_NAME and HTTP_HOST

    Does anyone have a suggestion as to why I am getting the 502 on the phone emulators.. I really think I am close to having this.
    Thanks.

  33. Daniel says:

    I found a similar tutorial here

    http://www.intac.net/how-to-make-your-site-compatible-for-cell-phones/

    Why do I need to convert to .php from html fo his to work and not yours?

    If i must convert to php then how do you suggest I do so?

    I understand a good amount of how to use the different html css and javascript codes but have very little knowledge of php. I’d greatly appreciate any help you are willing to give.

  34. Robert Eisenstein says:

    Daniel – great site link !
    I’m dying to make this work, but my developer said that the instructions on the link you sent are basically the same as in this post, thus, it will result in the same error.
    We tried this on our website after fully following the directions and when I try to use the global append and prepend directives in php.ini, I get fatal errors on the website. It’s a strange File not included error when trying to include the global appends and prepends. It appears we cannot set a path for these files via php.ini. We had it in that directory and had it all working. The global_prepend messes up the sessions that are required for using the members admin section.

    Also, the thing is that with a global prepend, I cannot see any way to exclude files….?
    Basically, it looks like as long as you have to use sessions, this will not work as you cannot pick and choose which files to want appended and prepended. It is a php.ini setting that applies to all files on the server.

    Any suggestions?

  35. Steven says:

    Mike,
    I followed your Four-Step instruction trying to make our company site mobile friendly.But this step #4 keeps making our site disappear. I guess I just do not have the knowledge to make the correct carriage returns after copying the scripts using my browser. Is there any way to show me how to complete this step correctly? I will appreciate it so much.
    Steven Zhang
    ESSC Group

  36. Zhang says:

    Mike,
    I followed your Four-Step instruction trying to make our company site mobile friendly.But this step #4 keeps making our site disappear. I guess I just do not have the knowledge to make the correct carriage returns after copying the scripts using my browser. Is there any way to show me how to complete this step correctly? I will appreciate it so much.
    Steven Zhang
    ESSC Group

  37. John says:

    Hi,

    I have setup the code above to mirrow my site but I keep getting errors as below. Can anyone help please

    Parse error: syntax error, unexpected ‘<' in /home/wsitepro/public_html/mobile/global_prepend.php on line 3

  38. Mike says:

    Not sure if it was mentioned, but you have to remove all the from the apphend/prepend files as they should not be there. Should work for most people after that. To see an example, I used it on a site here: http://mobile.marianoagency.com. There is a link to the full site so you can see the difference. Of note, I added a logo to the output so there is some color on the page. I may at some point alter the code so I can add tags to the page templates which would allow me to control the mobile site content. Overall, this is a great way to go mobile without building a true mobile site.

  39. June says:

    Hi, I have looked at the comments and am confused by your last comment- it appears to leave out some pertinent info.

    “Not sure if it was mentioned, but you have to remove all the from the apphend/prepend files as they should not be there. “

    What exactly needs to be removed? It doesn’t say.

  40. MikeB says:

    I’m on Dreamhost, but as others have pointed out, specifying PHP to run as non-CGI is no longer an option. Is there a work-around? Thanx!

  41. Thank you so much for this info. I had forgotten I used this on one of my other sites. I have just carried out your instructions from my new site, but when viewing on a Nokia phone it still isn’t quite right and don’t know how to fix it. Not all the table widths are the same, you will see my navigation (top) and navigation (bottom) and bottom table are bigger than the rest, HELP. Now please, you have a real dummy here and most of your techy instructions I would not understand, I am all self taught, hence my sites are very basic. If anyone can help, I would be most grateful as the majority of visitors seem to be viewing my site via a mobile phone. You are all amazing and don’t know what I would have done over the years without. :-)

Shared
The Ocean in 185 Lines of Javascript:

Mesmerizing. Try tweaking some of the variables in the “sea” section of the code.

“"Design had been a vertical stripe in the chain of events in a product’s delivery; at Apple, it became a long horizontal stripe, where design is part of every conversation.””
Why I Just Asked My Students To Put Their Laptops Away:

A great essay about how toxic everyday distractions can be.

Humanity's deep future:

A group of researchers at the Future of Humanity Institute talk about where our race may be going and how artificial intelligence could save or kill us all.

Steve Jobs speaks about the future at the International Design Conference in 1983:

31 years later, it’s safe to say this is one of the most prescient speeches about technology ever delivered. Jobs covers wireless networking, tablets, Google StreetView, Siri, and the App Store (among other things) many years before their proliferation. A fantastic listen.

How to travel around the world for a year:

Great advice for when you finally find the time.

LiveSurface:

A fantastic app for prototyping your design work onto real world objects like billboards, book covers, and coffee cups. This seems like just as great of a tool for people learning design as it does for experts.

50 problems in 50 days:

One man’s attempt to solve 50 problems in 50 days using only great design. Some good startup ideas in here…

How to Do Philosophy:

If you’ve ever suspected that most classical philosophy is a colossal waste of time, Paul Graham tells you why you’re probably right.

TIME: Why Medical Bills Are Killing Us:

Stephen Brill follows the money to uncover the pinnacle of corruption that is the U.S. Health Care system. A must-read article if there ever was one.

DIY Dot Org:

A beautifully designed site full of fun and challenging DIY projects. I could spend months on here.

The Steve Jobs Video Archive:

A collection of over 250 Steve Jobs videos in biographical order

Self-portraits from an artist under the influence of 48 different psychoactive drug combos.

Water Wigs are pretty amazing.

David Pogue proposes to his girlfriend by creating a fake movie trailer about them and then getting a theater to play it before a real movie. Beautiful and totally awesome.