Redirect Headless WordPress

June 02, 2019 - posted by Josh Smith

I love the idea of a headless site. Anyone who gets me to open up about my development obsession…Gatsby. While this isn’t necessarily a post about Gatsby, I did use it to create my blog’s frontend. It’s great in combination with WordPress because it provides great performance while giving editors the familiar Admin experience that many have come to love. I did discover that I need to make some adjustments however to my set.

Since I use WordPress as well as headless CMS I need to maintain the WordPress site. WordPress requires the use of a theme to provide work and I keep my WordPress installation on a separate domain. I don’t want people accidentally discovering my content presented on the wrong domain. I had to redirect any inadvertent travelers to where I want them; on my .com domain. It’s a relatively straight forward process that I’ll outline below, but here are the basics.

  1. Redirect anything from my WordPress frontend data domain to my .com domain.
  2. Allow Admins (me) to log into the WordPress installation

I experimented with Whitelisting my IP address or something similar but decided to just go with the 3xx redirect. Let’s get started, it won’t take long.

Redirect WordPress Frontend Visitors

First I created a new theme, but not just any theme. I created Headless WP an absolute minimum theme. Find Headless WP here on my GitHub. The theme does almost nothing except provide a couple hooks that I have written about and redirect frontend visitors.

In my index.php file, the file that starts the user’s view, I added the following snippet.

<?php

$newURL = get_option( 'headlesswp_setting_name' );

/**
 * @param $url
 * @param int $statusCode
 * Primary way to redirect front-end visitors away from this URL...but there are backups. -JMS
 */
function redirect( $url, $statusCode = 301 ) {
   header( 'Location: ' . $url, true, $statusCode );
   die();
}
redirect( $newURL, 301 );

?>
<meta content="0;url=<?php echo $newURL; ?>" http-equiv"refresh">

<script type="text/javascript">
    window.location = '<?php echo $newURL; ?>';
</script>

There are only a few lines, but that’s all I need. Let’s go through the code.

Starting at about line 10, I created a function to redirect any visitor then die. That function gets called right away so it happens before the page is even painted. You’ll notice a variable at the top called $newURL which I get from the WordPress function get_option. When I created the function I set the default redirect code to 301 which means that this redirection is permanent and should be treated by anything regarding SEO accordingly. Moz, a trusted authority, has a concise explanation of redirects on their site. I recommend reading it if you’re just getting into the technical bits of SEO and redirection. When I call the function, I also pass in the 301 as a parameter, albeit redundantly.

I created a field in my settings page to add the location to which I want my users redirected to. In my case, it’s my .com site, https://www.efficiencyofmovement.com. Instead of the variable with the slightly more complex settings page, you can just hardcode your redirect location here and call it a day. I wanted a settings page so I’ll walk through that too.

Create a Settings Field in WordPress

I created a file called, includes/settings.php. In that, I wrote the following snippet.

<?php
/**
 * Setup the new field on the General Settings page
 */
function headlesswp_settings_api_init() {
   // Add the section to general settings so we can add our fields to it
   add_settings_section(
      'headlesswp_setting_section',
      'Redirect your Headless WP',
      'headlesswp_setting_section_callback_function',
      'general'
   );

   // Add the field with the names and function to use for our new settings, put it in our new section
   add_settings_field(
      'headlesswp_setting_name',
      'New URL',
      'headlesswp_setting_callback_function',
      'general',
      'headlesswp_setting_section'
   );

   // Register our setting so that $_POST handling is done for us and
   // our callback function just has to echo the <input>
   register_setting( 'general', 'headlesswp_setting_name' );
} // headlesswp_settings_api_init()

add_action( 'admin_init', 'headlesswp_settings_api_init' );


// ------------------------------------------------------------------
// Settings section callback function
// ------------------------------------------------------------------
//
// This function is needed if we added a new section. This function
// will be run at the start of our section
//

function headlesswp_setting_section_callback_function() {
   echo '<p>If you want to redirect your WordPress instance, add the new URL here</p>';
}

// ------------------------------------------------------------------
// Callback function for our example setting
// ------------------------------------------------------------------
//
// creates a checkbox true/false option. Other types are surely possible
//

function headlesswp_setting_callback_function() {
   echo '<input name="headlesswp_setting_name" id="headlesswp_setting_name" type="url" class="regular-text code" value="' . get_option( 'headlesswp_setting_name' ) . '" /><p>If you want this installation to redirect add a URL here.<br> This is useful for when you only want your WordPress to serve data via the WP REST API or similar API.</p>';
}

All this does is create a single input field with a button on the main settings page at the bottom. In that field, I can add my URL that I want my errant visitors to go to. WordPress will pick that up and insert it into the aforementioned index.php page that gets built and almost renders to the user but is redirect just before.

Summary

So there is nothing mind-blowing here, in fact, most of it is cut and pasted from the WordPress documentation, which is what that is for. I just thought it was important for users of a headless site to redirect their data source URL to the actual site that they want their users to visit and consume content.

© 2019 All Rights Reserved

Designed by Josh at Efficiency of Movement