If you wonder why we are writing this post about Nginx, and nothing about Apache, the reason is simple: WP-AppKit is compatible with Apache, by default. Well, it will be completely with version 0.5 (see https://github.com/uncatcrea/wp-appkit/issues/167), coming soon.

TL;DR: If you directly want to know what to do with your Nginx configuration, go to the corresponding chapter.

Doing It The WordPress Way

So, does this means WP-AppKit is not fully compatible with Nginx? Of course not. But Nginx works a bit differently than Apache, especially regarding configuration and rewrite rules.

WordPress itself doesn’t handle automatically Nginx configuration, and if you try to activate permalinks on such an installation, you’ll be redirected to this codex page, explaining how you can make it work correctly.

This post does the same thing about WP-AppKit.

Under The Hood

You may (or may not) know that WP-AppKit provides 2 main features:

  1. previewing an app directly in the browser
  2. exporting all needed files to create a real app, connected to your WordPress website

Plus, we allow you to create and/or install your own theme to manage the look and feel of your app.

These features all need data coming from your website: your content of course, and also what you configured in the app edit screen or even your theme’s files (templates, scripts, images). In a preview context, be able to retrieve everything correctly requires us to define URLs where we can go get it.

Let’s take an example: config.js file. It is needed by WP-AppKit app core to set some important values. In fact, you are partially setting these values from the backoffice form, for example by choosing which theme you want to use.
When you export your app to build it with PhoneGap Build, it’s automatically generated and included into the zip you download.
But, when you’re previewing your app in a browser, it’s retrieved thanks to a given URL. This URL looks like wp-content/plugins/wp-appkit/app/config.js?wpak_app_id=my-app where wp-content/plugins/wp-appkit/ is WP-AppKit’s folder of installation, and my-app is your app slug.

To be honest, all other files are retrieved thanks to similar URLs. For example, require.js is taken from wp-content/plugins/wp-appkit/app/vendor/require.js.

Then, what’s the difference and what’s so special with config.js? The reality of it! Indeed, config.js doesn’t really exist. It’s dynamically generated, on demand.

And that’s where WordPress rewrite rules don’t play in our favor, because they enforce each file within wp-content/ folder to be real, or they’ll trigger a 404 error. You know, the ugly one, even before WordPress is called at all.


Note: it’s even true for both wp-admin/ and wp-includes/ folders as well.

We Will Rule The World

All that being said, the solution to make your browser preview work as expected is to add some rewrite rules before WordPress-related ones.

Single Site Install

If you run WordPress in a single site (standard) install, here are the rules you’ll have to add:

location ~ .*/wp-appkit/app/config.(js|xml) {
    try_files $uri /index.php?$args;
location ~ .*/wp-appkit/app/themes/.* {
    try_files $uri /index.php?$args;
location ~ .*/wp-appkit/app/addons/.* {
    try_files $uri /index.php?$args;

Multisite Install

As of now, we didn’t test this type of installation on Nginx. Our guess is that the previous rules will work for subdomain configurations, and that you’ll have to add a prefix for subfolder configurations:

location ~ ([_0-9a-zA-Z-]+/)?.*/wp-appkit/app/config.(js|xml) {
    try_files $uri /index.php?$args;
location ~ ([_0-9a-zA-Z-]+/)?.*/wp-appkit/app/themes/.* {
    try_files $uri /index.php?$args;
location ~ ([_0-9a-zA-Z-]+/)?.*/wp-appkit/app/addons/.* {
    try_files $uri /index.php?$args;

Please feel free to comment on this post if you already tested it and you have some inputs for us about that.

Published by Lionel on March 3, 2016

Web Developer for an insurance company, WordPress since 2009, aware about front-end performance and curious about (almost) anything

Leave a Reply

Your email address will not be published. Required fields are marked *

Having questions?

FAQ | Tutorials | Documentation


Contact Us