back

Knowlegde

Knowledge Centre

Optimizing User Experience: Customizing Drupal's Error Pages

by editor | 02.04.2018

Optimizing User Experience: Customizing Drupal's Error Pages

401, 403, and 404 - we've all encountered these HTTP status codes throughout our exploration of the World Wide Web at least once in our lives. How do you feel when these error pages appear instead of what you're looking for?

Not finding what you're looking for is beyond frustrating. Therefore, these pages need to be as non-frustrating as possible to compensate for the initial disappointment and encourage users to continue browsing the website.

While error pages come included by default when building a website, the real question is: Should we leave them simple and unstyled, or should we try making the user's experience with them more engaging?

During DrupalCamp London, I discovered that many developers face the challenge of creating and customizing these pages. It all starts with designers trying to make everything engaging and non-stressful. Then, developers work to customize and bring these designs to life.

In my experience, you shouldn't just "let them be." These pages can have small, quirky elements that help users forget they didn't get their expected result - to forget and forgive the error.

Almost all my past projects have had styled error pages. I feel it's my responsibility to request designs for these pages whenever they might be overlooked.

How to Customize Error Pages in Drupal

Let's look at the different methods available:

Drupal 7 Approach

In Drupal 7, you have two main approaches:

Using the generic error template:

// page--error.tpl.php
<div class="error-page">
 <?php if ($messages): ?>
   <div class="messages">
     <?php print $messages; ?>
   </div>
 <?php endif; ?>
 
 <div class="error-content">
   <?php print render($page['content']); ?>
 </div>
</div>

2. Creating specific templates for each error type using a hook in your theme:

// template.php
function YOURTHEME_preprocess_page(&$variables) {
 // Get the current HTTP status code
 $status = drupal_get_http_header("status");
 
 if ($status == "404 Not Found") {
   // Create template suggestion for 404
   $variables['theme_hook_suggestions'][] = 'page__404';
 }
 elseif ($status == "403 Forbidden") {
   // Create template suggestion for 403
   $variables['theme_hook_suggestions'][] = 'page__403';
 }
 elseif ($status == "401 Unauthorized") {
   // Create template suggestion for 401
   $variables['theme_hook_suggestions'][] = 'page__401';
 }
}

Then create specific template files:

// page--404.tpl.php
<div class="error-404">
 <h1>Page Not Found</h1>
 <p>Sorry, but the page you were looking for could not be found.</p>
 <?php print theme('search_block_form'); // Optional: Add a search form ?>
</div>
// page--403.tpl.php
<div class="error-403">
 <h1>Access Denied</h1>
 <p>You don't have permission to access this page.</p>
 <?php if (!$logged_in): ?>
   <?php print drupal_render(drupal_get_form('user_login_block')); ?>
 <?php endif; ?>
</div>

You can then style these templates using your theme's CSS:

.error-404, .error-403 {
 text-align: center;
 padding: 50px 20px;
 max-width: 600px;
 margin: 0 auto;
}
.error-404 h1, .error-403 h1 {
 font-size: 48px;
 color: #e74c3c;
 margin-bottom: 20px;
}
.error-404 p, .error-403 p {
 font-size: 18px;
 line-height: 1.6;
 color: #555;
}

By implementing these customizations, you can create error pages that not only inform users about what went wrong but also provide a better user experience with helpful options like search functionality or login forms when appropriate.

Remember to clear your theme registry cache after adding new template files for Drupal to recognize them in bash

drush cc all

 

404
Top
default

Drupal 8+ Approach

For Drupal 8 and above, the implementation is different and more structured. Here's how to do it:

1. First, create a theme suggestion in your THEMENAME.theme file:

/**
* Implements hook_theme_suggestions_page_alter().
*/
function THEMENAME_theme_suggestions_page_alter(array &$suggestions, array $variables) {
 $route_name = \Drupal::routeMatch()->getRouteName();
 
 if ($route_name == 'system.403') {
   $suggestions[] = 'page__403';
 }
 if ($route_name == 'system.404') {
   $suggestions[] = 'page__404';
 }
}

2. Create your Twig templates for the error pages:

{# page--404.html.twig #}
{% extends "page.html.twig" %}
{% block content %}
 <div class="error-page error-404">
   <h1>{{ 'Page Not Found'|t }}</h1>
   <div class="error-message">
     <p>{{ 'The requested page could not be found.'|t }}</p>
   </div>
   {% if search_form %}
     <div class="search-block">
       {{ search_form }}
     </div>
   {% endif %}
 </div>
{% endblock %}
{# page--403.html.twig #}
{% extends "page.html.twig" %}
{% block content %}
 <div class="error-page error-403">
   <h1>{{ 'Access Denied'|t }}</h1>
   <div class="error-message">
     <p>{{ 'You do not have permission to access this page.'|t }}</p>
   </div>
   {% if not logged_in %}
     <div class="login-block">
       {{ drupal_block('user_login_block') }}
     </div>
   {% endif %}
 </div>
{% endblock %}

Add your CSS styling:


/* error-pages.css */
.error-page {
 text-align: center;
 padding: 4rem 2rem;
 max-width: 800px;
 margin: 0 auto;
}
.error-page h1 {
 font-size: 3rem;
 color: #e74c3c;
 margin-bottom: 1.5rem;
}
.error-message {
 font-size: 1.2rem;
 line-height: 1.6;
 color: #555;
 margin-bottom: 2rem;
}
.search-block,
.login-block {
 max-width: 400px;
 margin: 2rem auto;
 padding: 1rem;
 background: #f8f9fa;
 border-radius: 4px;
}

For more advanced customization, you can also create a custom controller:

// src/Controller/CustomErrorController.php
namespace Drupal\your_module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Response;
class CustomErrorController extends ControllerBase {
 public function error404() {
   $build = [
     '#theme' => 'error_404',
     '#search_form' => \Drupal::formBuilder()->getForm('Drupal\search\Form\SearchBlockForm'),
   ];
   
   return $build;
 }
 public function error403() {
   $build = [
     '#theme' => 'error_403',
     '#login_form' => \Drupal::formBuilder()->getForm('Drupal\user\Form\UserLoginForm'),
   ];
   
   return $build;
 }
}

Don't forget to clear the cache after making these changes:

drush cr 

Remember these important points:
- Always test your error pages in a development environment first
- Make sure your error pages maintain your site's branding
- Include helpful navigation options
- Consider adding a search functionality
- Make the error message clear but friendly
- Provide clear next steps for users

These customizations will help create a better user experience even when things go wrong. The key is to turn a potential frustration point into an opportunity to help users find what they're looking for or discover something new on your site.

I am sure there might be other ways to do this, but these are the methods I usually use and so far, they’ve never failed me.

So what is your favorite method of customizing an error page?

  • Knowlegde
    Knowledge Centre
    Fine-tuning LLaMA to Recreate Eminescu's Literary Style
    editor
  • Knowlegde
    Knowledge Centre
    A New Era Begins: Drupal CMS 1.0 Launches
    editor
  • Knowlegde
    Knowledge Centre
    Bringing AI to B2B
    editor

Post a Comment.