Configure Redirects

Review considerations and recommendations on how to handle redirect logic via PHP within your site's configuration file.


Configure redirects within settings.php (Drupal) or wp-config.php (WordPress), adjusting placeholder values within snippets as needed (e.g., example.com).

Considerations

PHP vs htaccess

Pantheon does not support managing redirects in .htaccess files, since they are ignored by NGINX for reduced resource consumption and increased efficiency. This configuration is standard across all Pantheon sites, and modifications to the nginx.conf file are not supported.

Using .htaccess is generally not recommended - even for sites running Apache. Instead, we suggest handling redirects in PHP within your site's configuration file. Some advantages of redirecting via PHP instead of .htaccess include:

  • Logic and decisions can be made that a web server would have no context for, as it's executable code with application state awareness. Conditional logic, regular expressions, and much more are possible.
  • Configuration tends to be more maintainable as Drupal and WordPress developers are typically more familiar with PHP than Apache rewrite rules.
  • Since settings.php and wp-config.php are parsed very early in the bootstrap process, redirects like this are "cheap" with low overhead. If you use a 301 redirect, the Pantheon Global CDN will cache it as well.

Avoid Excessive Redirects

When using multiple snippets, be sure to step through the logic. This is particularly important when redirecting to a common domain while also incorporating redirects for specific pages. All if conditional statements need to be in the correct order. For example, a wholesale redirect executed prior to redirects for specific pages would likely prevent the second statement from being evaluated.

Redirect to HTTPS and the Primary Domain

This redirect is considered best practice and recommended as part of the going live procedure. Configure this redirect after connecting a custom domain in the Site Dashboard when you're ready to launch the site. For details, see Launch Essentials.

The following configuration will redirect HTTP to HTTPS and enforce use of a primary domain, such as http://live-site-name.pantheonsite.io to https://www.example.com or http://example.com to https://www.example.com:

Add the following to wp-config.php, usually placed above /* That's all, stop editing! Happy blogging. */. Don't forget to replace www.example.com:

if (isset($_ENV['PANTHEON_ENVIRONMENT']) && php_sapi_name() != 'cli') {
  // Redirect to https://$primary_domain in the Live environment
  if ($_ENV['PANTHEON_ENVIRONMENT'] === 'live') {
    /** Replace www.example.com with your registered domain name */
    $primary_domain = 'www.example.com';
  }
  else {
    // Redirect to HTTPS on every Pantheon environment.
    $primary_domain = $_SERVER['HTTP_HOST'];
  }

  if ($_SERVER['HTTP_HOST'] != $primary_domain
      || !isset($_SERVER['HTTP_USER_AGENT_HTTPS'])
      || $_SERVER['HTTP_USER_AGENT_HTTPS'] != 'ON' ) {

    # Name transaction "redirect" in New Relic for improved reporting (optional)
    if (extension_loaded('newrelic')) {
      newrelic_name_transaction("redirect");
    }

    header('HTTP/1.0 301 Moved Permanently');
    header('Location: https://'. $primary_domain . $_SERVER['REQUEST_URI']);
    exit();
  }
}

Add the following to the end of your settings.php file (replace www.example.com):

if (isset($_ENV['PANTHEON_ENVIRONMENT']) && php_sapi_name() != 'cli') {
  // Redirect to https://$primary_domain in the Live environment
  if ($_ENV['PANTHEON_ENVIRONMENT'] === 'live') {
    /** Replace www.example.com with your registered domain name */
    $primary_domain = 'www.example.com';
  }
  else {
    // Redirect to HTTPS on every Pantheon environment.
    $primary_domain = $_SERVER['HTTP_HOST'];
  }

  if ($_SERVER['HTTP_HOST'] != $primary_domain
      || !isset($_SERVER['HTTP_USER_AGENT_HTTPS'])
      || $_SERVER['HTTP_USER_AGENT_HTTPS'] != 'ON' ) {

    # Name transaction "redirect" in New Relic for improved reporting (optional)
    if (extension_loaded('newrelic')) {
      newrelic_name_transaction("redirect");
    }

    header('HTTP/1.0 301 Moved Permanently');
    header('Location: https://'. $primary_domain . $_SERVER['REQUEST_URI']);
    exit();
  }
  // Drupal 8 Trusted Host Settings
  if (is_array($settings)) {
    $settings['trusted_host_patterns'] = array('^'. preg_quote($primary_domain) .'$');
  }
}

Add the following to the end of your settings.php file (replace www.example.com):

if (isset($_ENV['PANTHEON_ENVIRONMENT']) && php_sapi_name() != 'cli') {
  // Redirect to https://$primary_domain in the Live environment
  if ($_ENV['PANTHEON_ENVIRONMENT'] === 'live') {
    /** Replace www.example.com with your registered domain name */
    $primary_domain = 'www.example.com';
  }
  else {
    // Redirect to HTTPS on every Pantheon environment.
    $primary_domain = $_SERVER['HTTP_HOST'];
  }

  if ($_SERVER['HTTP_HOST'] != $primary_domain
      || !isset($_SERVER['HTTP_USER_AGENT_HTTPS'])
      || $_SERVER['HTTP_USER_AGENT_HTTPS'] != 'ON' ) {

    # Name transaction "redirect" in New Relic for improved reporting (optional)
    if (extension_loaded('newrelic')) {
      newrelic_name_transaction("redirect");
    }

    header('HTTP/1.0 301 Moved Permanently');
    header('Location: https://'. $primary_domain . $_SERVER['REQUEST_URI']);
    exit();
  }
}

Additional Redirects (Optional)

Implement scenario specific redirects as required by the site. Depending on the needs of the site, you may only need one, some, or none of the following.

Redirect to HTTPS

The following configuration will redirect HTTP requests to HTTPS, such as http://env-site-name.pantheonsite.io to https://env-site-name.pantheonsite.io or http://example.com to https://example.com:

// Require HTTPS across all Pantheon environments
// Check if Drupal or WordPress is running via command line
if (isset($_SERVER['PANTHEON_ENVIRONMENT']) && ($_SERVER['HTTPS'] === 'OFF') && (php_sapi_name() != "cli")) {
  if (!isset($_SERVER['HTTP_USER_AGENT_HTTPS']) || (isset($_SERVER['HTTP_USER_AGENT_HTTPS']) && $_SERVER['HTTP_USER_AGENT_HTTPS'] != 'ON')) {

    header('HTTP/1.0 301 Moved Permanently');
    header('Location: https://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    exit();

    # Name transaction "redirect" in New Relic for improved reporting (optional)
    if (extension_loaded('newrelic')) {
      newrelic_name_transaction("redirect");
    }
  }
}

Redirect from Subdomain to Subdirectory Path

The following configuration will redirect requests for subdomain.example.com to https://example.com/subdirectory/:

// Redirect subdomain to a specific path.
// Check if Drupal or WordPress is running via command line
if (isset($_ENV['PANTHEON_ENVIRONMENT']) && ($_SERVER['HTTP_HOST'] == 'subdomain.example.com') && (php_sapi_name() != "cli")) {
  $newurl = 'https://www.example.com/subdirectory/'. $_SERVER['REQUEST_URI'];
  header('HTTP/1.0 301 Moved Permanently');
  header("Location: $newurl");
  exit();

  # Name transaction "redirect" in New Relic for improved reporting (optional)
  if (extension_loaded('newrelic')) {
    newrelic_name_transaction("redirect");
  }
}

Redirect One Path to Another

The following configuration will redirect requests for example.com/old to https://example.com/new:

// 301 Redirect from /old to /new
// Check if Drupal or WordPress is running via command line
if (($_SERVER['REQUEST_URI'] == '/old') && (php_sapi_name() != "cli")) {
  header('HTTP/1.0 301 Moved Permanently');
  header('Location: https://'. $_SERVER['HTTP_HOST'] . '/new');
  exit();

  # Name transaction "redirect" in New Relic for improved reporting (optional)
  if (extension_loaded('newrelic')) {
    newrelic_name_transaction("redirect");
  }
}

Redirect Multiple Paths

The following configuration will redirect requests for example.com, example.com/old, example.com/another/path, and example.com/old-path to https://example.com/new-path-for-all:

$redirects = array(
  "/",
  "/old",
  "/another/path",
  "/old-path");

// 301 Redirect from multiple paths
// Check if Drupal or WordPress is running via command line
if ((in_array($_SERVER['REQUEST_URI'], $redirects)) && (php_sapi_name() != "cli")) {
  header('HTTP/1.0 301 Moved Permanently');
  header('Location: https://'. $_SERVER['HTTP_HOST'] . '/new-path-for-all');
  exit();

  # Name transaction "redirect" in New Relic for improved reporting (optional)
  if (extension_loaded('newrelic')) {
    newrelic_name_transaction("redirect");
  }
}

Redirect Multiple Subdomains

The following configuration will redirect requests for sub1.example.com, sub2.example.com, sub3.example.com, and sub4.example.com to https://new.example.com:

// Redirect multiple subdomains to a single domain.
// Check if Drupal or WordPress is running via command line
if (isset($_ENV['PANTHEON_ENVIRONMENT']) && ($_ENV['PANTHEON_ENVIRONMENT'] === 'live') && (php_sapi_name() != "cli")) {
  if (in_array($_SERVER['HTTP_HOST'], array(
    'sub1.example.com',
    'sub2.example.com',
    'sub3.example.com',
    'sub4.example.com'
  ))) {
    header('HTTP/1.0 301 Moved Permanently');
    header('Location: https://new.example.com'. $_SERVER['REQUEST_URI']);
    exit();

    # Name transaction "redirect" in New Relic for improved reporting (optional)
    if (extension_loaded('newrelic')) {
      newrelic_name_transaction("redirect");
    }
  }
}

Redirect Legacy UNIX-Style User Home Folder Paths

When transitioning from a system that used a tilde to indicate a home directory, the syntax is slightly different. Here's how you can parse out the username and relative path that the request was made for:

$request_parts = explode('/', $_SERVER['REQUEST_URI']);
$legacy_username = $legacy_path = '';
if (isset($request_parts[1]) && strpos($request_parts[1], '~') === 0) {
  $legacy_username = substr($request_parts[1], 1);
  // If FALSE, then the request was just to the username.
  $legacy_path = substr($_SERVER['REQUEST_URI'], (strlen($request_parts[1]) + 1));
}
if ($legacy_username) {
  // Your custom logic.
}

Redirect to Force Lowercase Letters

WordPress automatically forces lowercase letters within URLs using the sanitize_title_with_dashes() function in core.

Drupal sites can force lowercase letters using the following:

  1. Set general automatic alias settings to Change to lower case within the PathAuto module configuration (/admin/build/path/pathauto).
  2. Enable Case Sensitive URL Checking within the Global Redirect module configuration (/admin/settings/globalredirect).

See Also