Back

Dynamic 404, 422 & 500 Error Pages with Rails Internationalization (I18n)

Gonzalo Diaz

February 26,2020

Today we are going to learn how to localise 404 & 500 Error Pages when using Rails Locale Translations.

1. The first thing we are going to do is add a new errors_controller.rb

rails generate controller errors not_found internal_server_error unprocessable_entity
Now go to your controllers/errors_controller.rb file and should have find something like this:

class ErrorsController < ApplicationController
    def internal_server_error
      render(:status => 500)
    end

    def not_found
      render(:status => 404)
    end

    def unprocessable_entity
      render(:status => 422)
    end
end

2. Ok let's proceed to add the following routes in your config/routes.rb:

  match '/404' => 'errors#not_found', :via => :all
  match '/422' => 'errors#unprocessable_entity', :via => :all
  match '/500' => 'errors#internal_server_error', :via => :al
By using match  :via => :all  we are allowing the error pages to be displayed for any type of request (GET, POST, PUT for example).

3. Now we need to tell Rails to allow us to use those custom routes for error handling. Go to your config/application.rb and add this:

config.exceptions_app = self.routes
4. Now we need to remove our current 404, 422 and 500 HTML pages located in the public folder BUT before you do that make sure you save any styling or HTML you might have done.

rm public/{404,500}.html
5. Great, we are nearly there. Now make sure that you have an error folder in your views with the following files:

1. internal_server_error.html.erb
2. not_found.html.erb
3. unprocessable_entity.html.erb

You probably already know that these error pages are all being rendered in your layouts/application.html.erb file. In order to not repeat yourself, you may as well create a custom template for those files and the cool thing is that it will automatically work with your error folder.

app/views/layouts/errors.html.erb

Here's how my layouts/errors.html.erb looks like

<!DOCTYPE html>
<html>
<head>
  <title>Error!!</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
</head>

<body>
  <%= yield %>
</body>
</html>
6. Testing: now that we are all set, it would be easy for us to test these files just by going to  http://localhost:3000/404 or http://localhost:3000/500 but the reality you want to make sure that these pages are rending when one of those errors are happening so to test this locally go to your config/environments/development.rb and set this variable to false:

config.consider_all_requests_local = false
Make sure to restart your rails server and voila! You are all set!