Automated build and deploy on VIP Go

This document covers the steps to run a deploy process for built code on the VIP Go hosting platform. This build process should only be used for CSS, JS, and static resources, not for PHP (e.g. no composer install), or SVG files. It is not necessary to configure a build and a deploy process for VIP Go, and many teams will find this process unnecessary to their development workflow.

The following example describes how a production site is developed and deployed using a flow which includes a build step and a deploy step:

  1. Branch from master for a new feature
  2. Develop cleanly with only your source code committed to your new branch (at this point you won’t commit NPM installed modules, nor transpiled code, nor compressed images, etc)
  3. Commit any changes to your dependencies, e.g. package.json, package.lock, but .gitignore the directories and files that npm modifies, e.g. /node_modules/ and anything else that gets built
  4. Create a pull request, get it reviewed and approved, then merge to master
  5. Build: Your build steps run on the CI service (you are responsible for configuring the build process for your site)
  6. Deploy: Our deploy script commits and pushes the build code to the master-built branch (and from there it is immediately deployed to your production site)

We have specific instructions below for Travis CI or Circle CI. If you wish to use your own script, or to use your own CI service, you are welcome to do so, the instructions below and scripts referenced are provided as a convenience only.

How is Javascript reviewed when using automated build and deploy?

If you are on a plan where we review your code, we will review the Javascript that your team writes. We will not review the third party dependencies brought in by the build process.

You should commit all code that your team writes to your VIP Go GitHub repository, instead of including it during the build process.

In some rare cases we will review all the Javascript code for a site, including dependencies, and in this case we will ask you not to use this build and deploy process, instead committing all JS directly to your VIP Go GitHub repository.

How do I build my code?

It is up to you and your team to develop a method to build, e.g. run npm install, transpile, optimize, concatenate, minify, etc, your code. You should develop the method so that it can be automatically run by a script on a Continuous Integration (CI) service, without intervention from a human.

You should also ensure any versioning updates (needed for cache busting, etc) is part of the build process or part of the commit that triggers the build.

When running the build process for production, i.e. master-built, you should ensure that your build process does not include development dependencies. You might also want to ensure that your CI script tests the build, and flags any issues to your team.

What branches should I deploy built code to?

Your deployed branch should end in -built, e.g. if your working branch is master (for your production environment) then your built branch should be master-built, for your Develop environment your working branch should be develop and your built and deployed branch should be develop-built.

Should I commit directly to my built branches?

No. You should never deploy code to your build branches, e.g. master-built, you should only ever deploy to your working branch, e.g. master, which should then build the code and deploy a commit to your build branch.

Configuring builds on Circle CI

It’s a good idea to read the Circle CI getting started documentation (but don’t add the suggested Circle CI config at this point).

The following instructions reference the master and master-built branch, but can be adapted for other branches, e.g. develop and develop-built.

  1. Contact VIP to have us configure Circle CI for your repository, including adding a machine user to deploy the builds
  2. Create a new PR, and add or adapt a config for Circle CI:
    • If you have no Circle CI config in your repository, copy this config to .circleci/config.yml in your repo; you will need to add the build command(s) you’re using in the section under “@TODO: Configure build steps”
    • If you already have a Circle CI config, you’ll need to:
      1. Add the build command(s), referencing the section in our example config commented with “@TODO: Configure build steps”
      2. Add the two sets of two lines referenced by the “REQUIRED:” comments
  3. Once you hear back from VIP that your repository is set up for Circle CI, trigger a build by merging a PR to master, this can be a non-significant change like a code comment… it should be built by Circle CI, committed to your master-built branch, and pushed up to GitHub (verify the branch now exists on GitHub and contains the changes you made)
  4. Contact VIP again to have your environment changed to deploy from master-built
  5. …that’s it!

Configuring builds on Travis CI

It’s a good idea to read the Travis CI getting started documentation, but don’t add the Travis CI config at this point.

  1. Visit, authenticate with your GitHub account, and add your repository to Travis CI
  2. Create or adapt a config for Travis CI:
    • If you have no Travis CI config in your repository, copy this config to .travis.yml in your repo; you will need to add the build command(s) you’re using in the section under “@TODO: Configure build steps”
    • If you already have a config, you’ll need to:
      1. Add the build command(s), referencing the before_script section in our example config commented with “@TODO: Configure build steps”
      2. Add the two sets of two lines referenced by the “REQUIRED:” comments
  3. Ensure you have a machine user, this is a regular GitHub user account which is used purely for scripted functions, e.g. used by Travis CI to commit and push the built code (GitHub call this user a “machine user”):
    • If you have no dedicated “machine user” account, create a new GitHub account, named appropriately.
    • If you already have a machine user for your team, then use that account for the following steps.
  4. Setup a key pair for your machine user:
    1. Use the commandline on your local machine to create a public private key pair (documentation)
    2. Set the public portion of the key pair as a deploy key with write permissions on the GitHub repository (documentation)
    3. Add the private key as a setting on your Travis repository (see “Adding a deploy key in repository settings on Travis CI” below)
  5. Merge a PR to your master branch… it should be built by Travis CI, committed to your master-built branch, and pushed up to GitHub (verify the branch now exists on GitHub and contains the changes you made)
  6. Contact VIP to have your environment changed to deploy from master-built
  7. …that’s it!

Adding a deploy key as a repository variable on Travis CI

Please read these instructions through before executing the steps.

Add the public portion of the key as a deploy key on your GitHub repository; GitHub documentation on deploy keys.

Set the private portion of the key as a repository variable in the Travis settings. You will need to replace newlines with \n and surround it with double quotes, e.g. “THIS\nIS\A\KEY\nABC\n123\n”; Travis documentation on repository variables in settings.

You must set the “Display value in build log” toggle for the repository variable to “off”.

You must name the Travis setting that contains the key BUILT_BRANCH_DEPLOY_KEY.

Other Notes

Where is the source code for the deploy script?

You can see the source code on our Github repo Automattic/vip-go-build.

My CI service is down or broken, how do I deploy files?

The step that you use to build files in your CI service should be scripted, by the nature of CI tasks. You should be able to follow this process:

  1. Clone the application repo.
  2. Checkout the working branch with the code you need to build (e.g. master).
  3. Run your build process (e.g. npm install).
  4. Checkout the built branch (e.g. git checkout master-built).
  5. Verify your changes; they should only include built code (and not development modules and dependencies).
  6. Commit and push the changes the remote repository (e.g. git push origin master-built).
    • Note: you do not need to open a PR, unless you would like a quick validation review from the VIP team.
  7. Once the code is pushed, the VIP Go infrastructure will detect the changes and deploy them to your application.

Loading Gutenberg on VIP

On the WordPress VIP Go platform, Gutenberg editor is opt-in. If you do nothing, legacy editing experience will be preserved. If you wish to enable Gutenberg, load it in your theme code using the helper function wpcom_vip_load_gutenberg().

You can load Gutenberg everywhere, or selectively by post ID (load only for specific posts) and post type (load only for specific post types). It is agnostic about whether Gutenberg is loading from core or via the plugin, allowing for a seamless transition.

Loading Gutenberg

Prior to WordPress 5.0, you will need to commit the Gutenberg plugin in the /plugins directory of your repository. There is no need to activate it.

Loading behavior is controlled by the wpcom_vip_load_gutenberg() function, to be added in your theme/functions.php. Calling this function without its single optional parameter causes Gutenberg to load on all post-edit screens.

An optional associative array of criteria can be passed. The possible keys and values are:

  • load (Int): 0|1: never or always load Gutenberg
  • posts (Array of post_ids): loads Gutenberg for the specified post_ids
  • post_types` (Array of post_types): loads Gutenberg for the specified post types.


In theme/functions.php:

if ( function_exists( 'wpcom_vip_load_gutenberg' ) ) {

Load Gutenberg for all posts.


wpcom_vip_load_gutenberg( [ 'load' => 0 ] );

Do not load Gutenberg for any posts.


wpcom_vip_load_gutenberg( [ 'post_ids' => [ 12, 13, 122 ] ] );

Load Gutenberg for posts with ids 12, 13 and 122.


wpcom_vip_load_gutenberg( [ 'post_types' => [ 'test', 'scratch' ], 'post_ids' => [ 12 ] ] );

Load Gutenberg for post_id 12 and all posts of type test and scratch


The typical use case is as shown above, the parameters do not change except when theme code is updated.

If making more dynamic changes, note that the parameter supplied is persisted in a site option; when the parameters are changed in code, one page load is necessary to update the site option before the editor can use the new setting.

In rare cases you may prefer a different Gutenberg transition solution (eg Classic Editor). Thus, Ramp can be disabled:

// in vip-config.php
define('VIP_GO_DISABLE_RAMP', true')

Local Development

wpcom_vip_load_gutenberg() and the above functionality is available by default on your VIP Go Development Environment.

It is also separately available in the Gutenberg Ramp plugin, available here. If you are experimenting with this plugin in a non-Go development environment please be aware that the name of the function differs slightly on the VIP vs public version (although it accepts the same parameters). Also, the UI is intentionally switched off on the VIP version so that developers maintain control, rather than wp-admin users. Contributions are welcome, via the plugin repository.

How to disable the privacy tools in WordPress 4.9.6

WordPress 4.9.6 and above will include five new GDPR tools: a privacy policy page, a privacy policy editing helper, a personal data export tool, a personal data erasure tool, and a permissions checkbox that is used with comments.

You can learn more about the release schedule and current feature set for WordPress 4.9.6 on the site.

On the VIP platform these tools will be disabled. On the VIP Go platform these tools will be available, but clients can choose to disable them. By default, the tools are disabled in Multisite for single-site administrators, but are still available for Super Admins.

You can use the map_meta_cap() filter to hide the following tools for all users:

  • privacy policy page
  • privacy policy editing helper
  • personal data export tool
  • personal data erasure tool

If you just want to restrict access to a small group of users (admins for example) the user_has_cap() filter would work as well, with some modifications.

* Disable the privacy tools added in WordPress 4.9.6.
* @param array $required_capabilities The primitive capabilities that are required to perform the requested meta capability.
* @param string $requested_capability The requested meta capability
* @param int $user_id The user ID.
* @param array $args Adds the context to the cap. Typically the object ID.
* @return array The primitive capabilities that are required to perform the requested meta capability.
function disable_496_privacy_tools( $required_capabilities, $requested_capability, $user_id, $args ) {
$privacy_capabilities = array( 'manage_privacy_options', 'erase_others_personal_data', 'export_others_personal_data' );

if ( in_array( $requested_capability, $privacy_capabilities ) ) {
$required_capabilities[] = 'do_not_allow';

return $required_capabilities;
add_filter( 'map_meta_cap', 'disable_496_privacy_tools', 10, 4 );

The permissions checkbox that is used with comments, can be disabled using the comment_form_default_fields filter.

Asynchronous publishing actions on VIP Go

Often when a post is published, there’s a number of actions associated with that publication. Some of those actions can take a while to perform, for example syndicating content out to sibling sites, pushing to social media, etc.

On VIP Go you can easily offload actions to be processed asynchronously on the Cron infrastructure for your site when a post is published or transitions status. Offloading actions reduces the processing time required for your publish action, which makes for a much faster and nicer publishing experience for your editors.

How to offload actions

Offloading an action on publish for asynchronous processing is as simple as changing the publish action hook to one of our async_ equivalents. The hooks we have available for asynchronous processing are:

  • async_transition_post_status, the asynchronous equivalent of transition_post_status (core hook docs)
  • async_{$old_status}_to_{$new_status}, the asynchronous equivalent of {$old_status}_to_{$new_status} (core hook docs)
  • async_{$new_status}_{$post->post_type}, the asynchronous equivalent of {$new_status}_{$post->post_type} (core hook docs)

This hypothetical code example splits off some functionality to be processed as the post is published, and some longer running functionality to be processed asynchronously:

 * Runs when a post of type `post` is published.
function my_post_publish_actions() {
	// This function performs quick actions,
	// and things which must happen immediately
add_action( 'publish_post', 'my_post_publish_actions' );

 * Runs asynchronously, when a post of type `post` is published.
function my_slower_post_publish_actions() {
	// This function performs slower actions,
	// like syndication and other longer 
	// running tasks
add_action( 'async_publish_post', 'my_slower_post_publish_actions' );

The code which powers our asynchronous offloading functionality works by scheduling an immediate Cron event to be processed on our dedicated Cron infrastructure, during which these async_* action hooks are called.


The asynchronous actions will be processed on separate infrastructure to the web requests; this means that the asynchronous action will not have access to anything which has been placed in the global context, or access files placed in the System temp directory, etc.

Setting Up the Ads.txt File

What is ads.txt?

It’s an IAB-approved text file to prevent unauthorized sales of inventory.  You can read more about it on their website:

Setting It Up

Since requirements specify that the /ads.txt file must be located in the root domain, we highly recommend to place the ads.txt file in your theme and then, create a rewrite rule for the URL. Here is an example for VIP platform:

// TODO: change `my_theme` prefix to my theme's prefix!
 * Register the rewrite rule for /ads.txt request.
function my_theme_adstxt_rewrite() {
	add_rewrite_rule( '^ads\.txt$', 'index.php?my_theme_adstxt=true', 'top' );
add_action( 'init', 'my_theme_adstxt_rewrite', 10 );

 * Filter the list of public query vars in order to allow the WP::parse_request
 * to register the query variable.
 * @param array $public_query_vars The array of whitelisted query variables.
 * @return array
function my_theme_adstxt_query_var( $public_query_vars ) {
	$public_query_vars[] = 'my_theme_adstxt';
	return $public_query_vars;
add_filter( 'query_vars', 'my_theme_adstxt_query_var', 10, 1 );

 * Hook the parse_request action and serve the ads.txt when custom query variable is set to 'true'.
 * @param WP $wp Current WordPress environment instance
function my_theme_adstxt_request( $wp ) {
	if ( isset( $wp->query_vars['my_theme_adstxt'] ) && 'true' === $wp->query_vars['my_theme_adstxt'] ) {
		 * Set proper content-type per specification in
		 * :
		 * The HTTP Content-type should be ‘text/plain’, and all other Content-types should be treated
		 * as an error and the content ignored.
		header( 'Content-Type: text/plain' );

		// The code expects an existing ads.txt file in the root of your active theme.
		echo file_get_contents( get_stylesheet_directory() . '/ads.txt' );
add_action( 'parse_request', 'my_theme_adstxt_request', 10, 1 );

On, there should be no need to flush your rewrite rules, as it happens automatically upon deploy. For VIP Go, and in cases where the redirect does not working as expected, please head to VIP => Rewrite Rules and hit the “Flush Rewrite Rules” button.

Note: this is just one way to go about doing so; if there is another way that works better for your theme, feel free to employ it!

If you’d like to be able to modify and validate your ads.txt file from the admin interface, the Ads.txt Manager plugin from VIP Featured Partner 10up allows you to do so, and is approved for use on both VIP and VIP Go.

Restricting access to a site hosted on VIP Go

Many VIP Go clients have the requirement to control access to their site so only a specific group of users are able to access it. For launched production sites, your solution must be architected around anonymous users and authenticated users:

Anonymous users can be served with a login screen, a page with information on how to authenticate, or a simple denial notice, etc. This response should be served with an HTTP Status of 200, and you may choose to include information about how a user can authenticate to access the site fully. This response will be cached by the VIP Go page cache.

Authorized users must log in using a WordPress user account, and you can tailor the output to these users, vary the content for different users, etc. Logged in users bypass VIP Go page caching. If your organization has a Single Sign On system, then integrating this with your VIP Go site will smooth the log in experience for your users (see “Single Sign On (SSO)” below).

Requirements and Notes

Single Sign On (SSO)

Single Sign On systems provide a central log in system for all of your company’s services, they simplify life for your users by removing the need to configure separate usernames and passwords for each system each user needs to use. VIP Go allows integration with SSO systems to simplify authentication.

Your SSO integration must create local WordPress user accounts and use standard WordPress authentication cookies, in order to work correctly on the VIP Go platform. These accounts can be restricted such that they cannot user passwords to sign in and are required to authenticate via your SSO flow instead.

The VIP Support team will require access to your site, so you must allow users from inside our network to bypass your SSO integration and log in as usual with a username and password. Requests from inside our authenticated network can be identified by checking that the A8C_PROXIED_REQUEST constant is true (see “Checking for requests from inside Automattic’s network” below). If you have any questions about this, please contact us and we’ll be happy to help.

The WordPress REST API

Your site content can be accessed via the WordPress REST API, so if you need to constrain access to site content then your solution must take this into account.

As many VIP Go features utilise the WordPress REST API, we do not allow sites to disable this API completely. If you need to restrict access to your site via the WordPress REST API, you should force authentication for API endpoints.

Whitelisting access by IP address

If you need to restrict the display of certain content to authorized users, then those users must be logged in, this is to ensure that responses to these users are not cached. During the log in process (and on every subsequent request) you can hook into WordPress to reject the log in if the user is not on an authorized IP address.

In order for the VIP team to support your site our users must still be able to log in to your site, despite not being on your IP whitelist. Requests from inside our authenticated network can be identified by checking that the A8C_PROXIED_REQUEST constant is true (see “Checking for requests from inside Automattic’s network” below).

You must not add IP address restrictions for anonymous users in PHP code, and it is not possible for us to configure your site to restrict access to a limited range of IP addresses in our web server or caching layers. Implementing IP restrictions in PHP code will cause issues within the cached responses to your site; consider the following scenario:

  1. User A visits page 1, this user is from an “authorized IP address”
  2. The VIP Go site serves a tailored response to User A, showing them content only available to certain specific users
  3. The VIP Go page cache caches the response
  4. User B visits page 2, this user is not from an “authorized IP address”
  5. The VIP Go page cache responds to User B with the cached information, i.e. the content which was served to User A, content which was only intended to be available tocertain specific users

Restricting access to user uploaded files

Files which are uploaded to your VIP Go site media library are served by the VIP Go Files Service. It is not possible to control access to your uploaded files via authentication; i.e. it is not possible to restrict access to a file to logged in users only, nor to users from particular IP addresses.

You must not block xmlrpc.php

Various VIP Go platform services use the /xmlrpc.php endpoint, so this must not be blocked by any access restrictions you put into place. Access to the /xmlrpc.php endpoint is restricted to authorised requests only, so additional constraints are not necessary.

Checking for requests from inside Automattic’s network

The following code example shows how to check that the request is from a user inside Automattic’s network.

if ( defined( 'A8C_PROXIED_REQUEST' ) && true === A8C_PROXIED_REQUEST ) {
    // The request originates from VIP (Automattic)

Can I mark some entries as “no cache” to avoid issues with caching?

Anonymous user requests should always be cached, and you must not send “no cache” headers to anonymous users. If you want to show the user restricted content and not have this content cached the user should be logged in, logged in users bypass the VIP Go .

Is there a scaling issue with so many uncached users browsing my site?

Your site can scale to handle many thousands of logged in users with the help of our standard VIP Go guidelines for scaling websites. We are happy to talk through your particular use cases, please get in touch.

Basic Authentication for un-launched sites

Basic Authentication is the “pop up” prompt for a username and password which is displayed by your browser when you visit a site which is protected in this way.

While a site is under development, and for non-production sites, we can set up Basic Authentication for you. If you’d like us to do this, please contact us and we’ll be happy to do so.

It is not possible for launched production sites to use Basic Authentication, as this form of access control breaks various VIP Go platform services.

Maintenance Mode

While a site is under development, you can also use the Maintenance Mode plugin to restrict access to your site. Add this plugin to your site by following the instructions for enabling plugins on VIP Go and configuring Maintenance Mode.

Setting up your Development Environment

Like all software development, you should develop and test your code in your local development environment before committing the code to VIP. This document will help you set up an environment to aid development of your VIP hosted site.

Please note: This document relates to the VIP platform. VIP Go related documentation can be found here.

Caveats is a large web application that has been developed over the past 10+ years. Please note that the environment setup described here will not provide a 1:1 copy of your production environment. While we’ve tried to bridge various gaps, many features are very challenging to reproduce locally and environmental differences will exist. A non-exhaustive list of these differences can be found here.

We’re also happy to help guide and assist you with any concerns/issues you have with these differences.

Getting Started

  1. Install a local Multisite WordPress environment. We recommend Chassis or VVV.
    • Use Chassis if you want an environment that’s simple yet powerful. It’s a minimalist development setup that boots up fast and gets out of the way.
    • Use VVV if you want an environment that comes with lots of features, is highly extensible, and can run many different site configurations.
    • You can also roll your own setup (like something built on Docker).

    Note: Your environment should be be set up as a Multisite (Chassis has a config flag; VVV requires a custom site template; and custom setups can follow the Codex).

  2. Install VIP Plugins and Helpers to wp-content/themes/vip/plugins:
    svn co wp-content/themes/vip/plugins

    You should svn up daily to ensure you’re working with the latest code.

  3. Install VIP mu-plugins to wp-content/mu-plugins:
    git clone --recursive wp-content/mu-plugins

    You should git pull daily as well to ensure you’re working with the latest code.

    The readme covers other environment-specific things like concatenation and caching that you may want to set up as well.

  4. Install your theme to wp-content/themes/vip/{your-theme}. If you’re just starting out with VIP, please read through Anatomy of a VIP Theme to get an overview of what your theme should look like.


When set up correctly, your wp-content directory should likely look something like:


The Stack

As of March 30, 2018, we are using the following pieces of software across our stack:

  • Debian Stable
  • PHP 7.2
  • MariaDB 10.2
  • NGINX (latest)
  • Memcached (latest)

Note that the one most likely to impact your day-to-day work is the PHP version.

WordPress Updates

We are usually running the latest stable release of WordPress core on

We try to provide adequate notice for releases of major versions on the platform. When a pending release is announced, we recommend switching over your local environment to use the beta tester plugin or a SVN checkout of trunk to make sure you’re running the latest version and can test for any issues before they are rolled out.

Your Content

You can use the built-in export/import functionality in WordPress to populate your local environment with test data. You can generate an export from your site’s Dashboard and then use either wp-cli or the Dashboard Importer to import the content. If you have issues exporting or importing, please get in touch and we’d be happy to help.

If you are just starting out and need some data to play with, check out the demo files that the Automattic Theme Team uses for building and testing new themes.

You can also use WP Options Importer to export/import options (like widgets, plugin settings, etc.).


You should always have debugging enabled in your local environment help catch errors as you develop:

// In your wp-config.php
define( 'WP_DEBUG', true );
define( 'SAVEQUERIES', true );

// Optional
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', true );

// Learn more:

Development Tools

We also recommend the following plugins and tools:

Note that these tools are meant for development/debugging only and should not be included in your theme or pushed to production.

Staging Environments

For staging environments, the only difference would be to use a hosting provider of your choice for your WordPress environment (some examples include DigitalOcean, AWS, and so on).

Commit and Deploy Webhooks

As well as receiving e-mail notifications, you can set up repository-specific commit and deploy webhooks for your VIP code.

Set up

To tell which webhooks to ping, simply add a wpcom-meta.php to the root of your repo with something like this;

 * Commit Webhook:
 * Deploy Webhook:

Committing that file is all you need to do to create the webhooks. If you have any difficulties, or need more information, don’t hesitate to open a ticket with us.

Note: Services, such as Slack, require data to be transformed into a standard format for their platform. So in this instance you would have to transform the data prior to passing it to Slack.

Commit Webhook

The commit webhook will provide the following data:

  • repo – The name of the repository.
  • theme – The name of the theme.
  • revision – The committed revision number.
  • committer – The username of the committer.

Deploy Webhook

The deploy webhook will provide the following data:

  • repo – The name of the repository.
  • theme – The name of the theme.
  • previous_revision – The previously deployed revision.
  • deployed_revision – The deployed revision number.
  • deployer – username of the person who deployed the revision.
  • revision_log – A log of commits between the previously deployed and newly deployed revisions.


As the audience of your website grows, it becomes more challenging to publish content that is relevant to all readers. Personalization gives you the ability to profile each user’s behavior and capture their preferences, allowing you to display more relevant content and ultimately, keep your audience engaged.

What is personalization?

Personalization can mean different things to different people but it mainly involves providing your audience with a more customized and engaging experience. It could mean that you’re providing content that is more relevant to their geographic location or that you’re providing them more relevant content based on what they’ve viewed or liked in the past. Personalization could also mean that your users are able to share content with each other and follow people or topics that they are interested in.


Before diving into using the most popular plugins for personalization, there are a few items that you would want to keep in mind, regardless of the type of personalization that you’re interested in. 

  • Sending data to the personalization vendor: If the personalization requires you to send them any data (user data, activity data, etc.),  you will have to include a javascript snippet in all of your pages. Be sure to choose a reliable third party vendor as slow response times on their end could affect your end-user experience.
  • Serving recommendations from the personalization vendor: As the recommendations for a specific type of user may change, the recommended list of content is typically sent dynamically from the personalization vendor’s systems. Some vendors store the user’s behavior in a cookie so that your users don’t have to rely on their service being online but make sure you understand what features of your site (if any) will be impacted if the service vendor’s systems go offline.
  • Limiting the user information that is shared: If you require users to sign in with their account, you have the added advantage of using their historical preferences to personalize. However, this would require you to share additional information with the personalization vendor. It is best to let your personalization vendor know just the username or a separate unique identifier for the user.
  • Supporting cross-channel interactions: If you want the flexibility to capture data from your users across various channels (social media, email, mobile apps, website, etc.), you will need a vendor that can unify data from all of these channels to a single user profile (typically based on the email address). Most personalization vendors that support cross-channel data gathering will also let you publish your recommendations through any of these channels.

Types of personalization

There are no limits to how you can personalize your content but the most popular options include:

Customer Identity & Access Management

Personalizations rely heavily on understanding who your customers are. A sophisticated customer identity and access management solution will help you identify your customers regardless of the device or channel they’re engaging from, allowing you to keep your message consistent across a diverse platform.

Janrain, a Featured Partner of VIP, provides a platform that combines your ability to acquire users across multiple digital and marketing channels. In addition to providing a Single Sign-On solution, they provide a hosted user database and provide integration for social sharing.

We have also had VIP clients use Gigya, another popular platform to securely manage and update user profiles, thereby giving you a great starting point to provide personal experiences.

Custom Social Network

If you have built a community, you may be looking to empower your users to share stories, like each other’s’ contributions and have a newsfeed of updates from the people or things that they follow.

The popular BuddyPress plugin built by the WordPress community provides a lot of social network features out of the box. It provides both private messaging and public sharing. However, the vision of some of our clients were better met by using a Featured Partner for custom development.

Predictive Marketing

You might have noticed that some sites have a ‘You might also like’ section, listing content related to what you have been reading. There is another variant of this personalization where content related to the current page is listed. These dynamically shortlisted links are more relevant to your users and have a higher click-through rate.

One of our featured partners: Sailthru, is the leading provider of personalized marketing communications. Their WordPress plugin makes it easy to provide personalized content through their Scout and Concierge modules. Scout provides content relevant to a page whereas Concierge provides content that is recommended for the specific user. Under the covers, both modules use predictive marketing algorithms to determine the best recommendations for your users.  We have had multiple VIP clients use Sailthru’s straightforward integration to personalize their content.

If you’re looking to add a simple ‘Related Posts’ section to your website,’s Related Posts feature may be all you need. It’s powered by the popular Jetpack addon, which uses Elasticsearch to analyze your content and understand its relevance to the rest of your website. You can finetune how the recommendations are displayed using the customization options.

Geo-specific content

As your audience grows, you might find it challenging to provide content that is engaging to your users regardless of where they’re from. Geo Uniques allows you to target distinct geographic markets with different content. You also have the option of defining custom location groups so that you can target groups smaller than countries.

Uploading video files

Your VIP site’s Media Library can be configured to accept video file types like these:

  • .mp4, .m4v (MPEG-4)
  • .mov (QuickTime)
  • .wmv (Windows Media Video)
  • .avi
  • .mpg
  • .ogv (Ogg)
  • .3gp (3GPP)
  • .3g2 (3GPP2)

To enable these file types on a VIP site, please open a support ticket.

Ready to get started?

Drop us a note.

No matter where you are in the planning process, we’re happy to help, and we’re actual humans here on the other side of the form. 👋 We’re here to discuss your challenges and plans, evaluate your existing resources or a potential partner, or even make some initial recommendations. And, of course, we’re here to help any time you’re in the market for some robust WordPress awesomeness.