Please follow the following steps to install PoP:

  1. Install the latest version of WordPress
  2. Download/clone PoP from the repository in GitHub on the same folder
  3. Create all required pages/categories/etc, to be found in each plugin’s config/constants.php file (eg: this file), and set those constants with their corresponding ID (there’s an issue to do this through scripts)
  4. Activate all plug-ins and the theme

Required 3rd-party plugins

Install and activate the following plugins, which are integrated with PoP (not all of them are mandatory, however PoP has yet not been tested without them):


PoP allows the configuration of the following properties, done in file wp-config.php:

Produce HTML on the server-side for the first-loaded page.

Load only the .js and .css that is needed on each page and nothing more.

If doing code splitting, load JS resources on 2 stages: critical ones immediately, and non-critical ones deferred, to lower down the Time to Interactive of the application.

(Only if doing code-splitting) When executing the /generate-theme/ build script, generate a single bundlegroup and/or a series of bundle files for each page on the website containing all resources it needs.

(Only if doing code-splitting) Generate the bundlegroup or bundle files on runtime, so no need to pre-generate these.

(Only if doing code-splitting) Pre-generate the mapping listing what resources are needed for each route in the application, created when executing the /generate-theme/ build script.

POP_SERVER_ENQUEUEFILESTYPE (resource|bundle|bundlegroup):
(Only if doing code-splitting) Choose how the initial-page resources are loaded:

  • “resource”: Load the required resources straight
  • “bundle”: through a series of bundle files, each of them comprising up to x resources (defined through constant POP_SERVER_BUNDLECHUNKSIZE)
  • “bundlegroup”: through a unique bundlegroup file

(Only if doing code-splitting) How many resources to pack inside a bundle file. Default: 4.

(Only if doing server-side rendering, code-splitting and enqueue type = “resource”) Choose how to include those resources depended by a module (mainly CSS styles):

  • “header”: Link in the header
  • “body”: Link in the body, right before the module HTML
  • “body-inline”: Inline in the body, right before the module HTML

Allow to extract configuration code from the HTML output and into Javascript files on runtime.

Include the minified version of .js and .css files.

(Only if not doing code-splitting) Insert script and style assets from a single bundled file.

Whenever available, use resources from a public CDN.

Re-order script tags so that they are included only after rendering all HTML.

Enable to set the application configuration through URL param “config”

Load an empty Application Shell (or appshell), which loads the page content after loading.

If doing server-side rendering, remove all database data from the HTML output.

Allows to replace the name of each module with a base36 number instead, to generate a smaller response (around 40%).

  • 0: Use the original name of each module
  • 1: Use both
  • 2: Use the base36 counter number

When mangling the template names (template definition type is set to 2), use a database of all template definitions, which will be constant over time and shared among different plugins, to avoid errors in the website from accessed pages (localStorage, Service Workers) with an out-of-date configuration.

If the template definition type is set to 2, then we can set namespaces for each plugin, to add before each template definition. It is needed for decentralization, so that different websites can communicate with each other without conflict, mangling all template definitions the same way. (Otherwise, having different plugins activated will alter the mangling counter, and produce different template definitions).

Create and re-use a cache of the settings of the requested page.

Common keys from the JSON code sent to the front-end are replaced with a compact string. Output response will be smaller.

Save special loaded-in-the-background pages in localStorage, to not have to retrieve them again (until software version changes).

Strip the output of all Javascript code.

Indicates that we are using all the output files produced from running /generate-theme/ in this environment, namely:

  • resourceloader-bundle-mapping.json
  • resourceloader-generatedfiles.json
  • All pop-memory/ files

When generating file resources.js, with the list of resources to dynamically load on the client, do not include those resources initially loaded in the website (through “loading-frame”).

Decentralization: enabling crossdomain

To have a website consume data coming from other domains, crossdomain access must be allowed. For this, edit your .htaccess file like this:

<IfModule mod_headers.c>
  SetEnvIf Origin "http(s)?://(.+\.)?(|$" AccessControlAllowOrigin=$0
  Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin

  # Allow for cross-domain setting of cookies, so decentralized log-in also works
  Header set Access-Control-Allow-Credentials true
  Header add Access-Control-Allow-Methods GET
  Header add Access-Control-Allow-Methods POST


PoP allows to mangle, minify and bundle together all required .css, .js and .tmpl.js files (suitable for PROD environment), both at the plug-in and website levels:

At the plug-in level (it generates 1 .js file + 1 .tmpl.js file + 1 .css file per plug-in):
execute bash -x plugins/PLUGIN-NAME/build/ for each plugin

At the website level (it generates 1 .js file + 1 .tmpl.js file + 1 .css file for the whole website):
execute bash -x themes/THEME-NAME/build/ for the theme

Executing the scripts requires the following software (I’ll welcome anyone proposing a better way to do this):

  1. UglifyJS
    To minify (as to reduce the file size of) JS files
  2. UglifyCSS
    To minify (as to reduce the file size of) CSS files
  3. Google’s minimizer Min
    To bundle and minify files. The min webserver must be deployed under http://min.localhost/.

The following environment variables are used in POP_APP_PATH, POP_APP_MIN_PATH and POP_APP_MIN_FOLDER. To set their values, for Mac, execute sudo nano ~/.bash_profile, then add and save:

export POP_APP_PATH=path to your website (eg: "/Users/john/Sites/PoP")
export POP_APP_MIN_PATH=path to Google's min website (eg: "/Users/john/Sites/min")
export POP_APP_MIN_FOLDER=folder name in min, where files to minimize are copied (eg: "PoP", with the folder being /Users/john/Sites/min/PoP/)

The script copies all files to minimize under folder POP_APP_MIN_FOLDER, from where it minimizes them. The structure of this folder must be created in advance, as follows:

for each theme:


for each plug-in:


Sign up to our newsletter:

Welcome to the PoP framework!
Break the information monopoly

the PoP framework is open source software which aims to decentralize the content flow and break the information monopoly from large internet corporations. Read more.