Rails static error pages
Find a file
heming 9f5018e0e2
All checks were successful
CI / Test on Ruby 3.4 (push) Successful in 51s
CI / Lint (push) Successful in 39s
CI / Test Coverage (push) Successful in 50s
CI / Build gem (push) Successful in 35s
Housekeeping: Delete files that do not belong in git
2025-06-15 06:38:38 +02:00
.forgejo Optimize workflow bundle caching strategy 2025-06-15 06:02:01 +02:00
app/controllers/rsep Enable middleware and auto-generation by default following Rails conventions 2025-06-14 23:18:16 +02:00
bin Remove all emojis from codebase 2025-06-14 12:05:32 +02:00
config Implement Rails asset pipeline integration with Propshaft 2025-06-14 23:02:20 +02:00
examples Consolidate demo application and rake task improvements 2025-06-14 02:49:47 +02:00
lib Bump version to 0.2.5 2025-06-15 06:27:31 +02:00
test Streamline test suite by removing redundant and external dependency tests 2025-06-15 03:32:52 +02:00
.gitignore Add editor-specific files to gitignore 2025-06-15 06:34:11 +02:00
.rubocop.yml Add comprehensive JSON error response support 2025-06-14 21:58:35 +02:00
.ruby-lsp.yml Configure Zed and ruby-lsp to use StandardRB for formatting and linting 2025-06-13 18:53:15 +02:00
.ruby-version Update Ruby version to 3.4.4 2025-06-13 23:53:53 +02:00
.yardopts Add comprehensive YARD API documentation 2025-06-15 04:30:23 +02:00
CHANGELOG.md Add custom template resolution for error-specific templates 2025-06-14 13:09:42 +02:00
Gemfile Reorganize dependencies and relax version constraints 2025-06-15 06:23:26 +02:00
Gemfile.lock Bump version to 0.2.5 2025-06-15 06:27:31 +02:00
GUIDE.md Update GUIDE.md title and formatting 2025-06-15 04:54:25 +02:00
LICENSE Replace MIT license with GPLv3 2025-06-13 19:49:00 +02:00
mise.toml Housekeeping: 2025-06-14 12:43:51 +02:00
Rakefile Disable Rails/RakeEnvironment RuboCop rule for coverage task 2025-06-15 01:05:59 +02:00
README.md Consolidate CI documentation into main README 2025-06-15 03:38:05 +02:00
rsep.gemspec Relax Rails version requirement to >= 7.0 2025-06-15 06:26:56 +02:00

Rsep

Rails Static Error Pages - Generate HTML files for HTTP error codes that match your Rails application's design.

Installation

Add to your Gemfile:

gem "rsep"

Then run:

bundle install
rails generate rsep:install

Features

  • Static HTML Generation: Creates error pages as static files for fast serving
  • Rails Integration: Uses your application's layout and styling
  • Automatic Middleware: Serves error pages with JSON API support (enabled by default)
  • Custom Templates: Per-error template resolution with fallbacks
  • Custom Content: Add text, HTML, images, or ERB templates to error pages
  • Internationalization: Built-in translations for English, French, German, Spanish, Japanese
  • Asset Pipeline Integration: Automatically generates during deployment
  • Development Preview: Live preview engine for testing error pages
  • Reverse Proxy Support: X-Sendfile headers for nginx, Apache, Lighttpd

Basic Configuration

# config/initializers/rsep.rb
Rsep.configure do |config|
  config.layout = "application"
  config.template = "rsep/default"
  config.output_path = "public"
  # config.enabled_errors = [:not_found, :internal_server_error, :forbidden]  # Defaults to 8 error codes
  
  # Enabled by default
  config.auto_generate_on_precompile = true
  config.middleware_enabled = true
end

Usage

Generate Error Pages

rails rsep:generate

Custom Templates

Templates are resolved in this order:

  1. Custom configured template (via config.set_template())
  2. app/views/rsep/not_found.html.erb (error symbol)
  3. app/views/rsep/404.html.erb (HTTP code)
  4. Default template

Template variables available:

  • @status_code - HTTP status code
  • @title - Error title
  • @details - Error description
  • @custom_content - Custom content blocks

Custom Content

Rsep.configure do |config|
  # Add text content
  config.add_custom_content(:not_found, {
    text: "The page might have been moved or deleted."
  })
  
  # Add HTML content
  config.add_custom_content(:not_found, {
    html: '<a href="/">Go Home</a>'
  })
  
  # Add images
  config.add_custom_content(:internal_server_error, {
    image: "/assets/server-error.png",
    image_alt: "Server maintenance"
  })
  
  # Use ERB templates
  config.add_custom_content(:forbidden, {
    template: "errors/access_denied",
    locals: { admin_email: "admin@example.com" }
  })
end

Internationalization

# Set locale
config.locale = :fr
config.locale = -> { I18n.locale }

# Add custom translations in config/locales/rsep.es.yml
es:
  rsep:
    errors:
      not_found:
        title: "Página no encontrada"
        details: "La página que buscas no existe."

Middleware Configuration

Rsep.configure do |config|
  config.middleware_enabled = true
  config.middleware_mode = :static  # or :dynamic
  
  # For nginx
  config.middleware_sendfile_header = 'X-Accel-Redirect'
  config.middleware_sendfile_mapping = {
    from: '/var/www/app/public',
    to: '/internal'
  }
end

Available Rake Tasks

# Core tasks
rails rsep:generate          # Generate error pages
rails rsep:status            # Show configuration
rails rsep:validate          # Validate setup
rails rsep:clean             # Clean generated files
rails rsep:preview           # Open preview in browser

# Internationalization
rails rsep:i18n:list         # List locales
rails rsep:i18n:generate[fr] # Generate for locale
rails rsep:i18n:check        # Check translations

# Development
rails health:check           # Run health checks

Development Preview

Mount the preview engine in development:

# config/routes.rb
Rails.application.routes.draw do
  mount Rsep::Engine => "/rsep" if Rails.env.development?
end

Visit http://localhost:3000/rsep for interactive preview.

Generators

# Generate templates
rails generate rsep:template custom_error
rails generate rsep:template --error-specific
rails generate rsep:template --all-codes

JSON API Support

The middleware automatically serves JSON responses for API requests:

{
  "error": "Not Found",
  "message": "The page you are looking for could not be found.",
  "status": 404
}

Reverse Proxy Configuration

nginx

error_page 404 /404.html;
error_page 500 502 503 504 /500.html;

location = /404.html { internal; }
location = /500.html { internal; }

Apache

ErrorDocument 404 /404.html
ErrorDocument 500 /500.html

Thruster

No configuration needed - automatically serves from public/ directory.

Controller Helpers

class ApplicationController < ActionController::Base
  include Rsep::ControllerHelpers
  
  def handle_not_found
    respond_to do |format|
      format.html { render_rsep_html(:not_found) }
      format.json { render_rsep_json(:not_found) }
    end
  end
end

Supported Error Codes

  • :bad_request (400)
  • :forbidden (403)
  • :not_found (404)
  • :not_acceptable (406)
  • :unprocessable_entity (422)
  • :internal_server_error (500)
  • :bad_gateway (502)
  • :service_unavailable (503)

Documentation

For comprehensive documentation including advanced configuration, reverse proxy setup, and contribution guidelines, see GUIDE.md.

Development

git clone <repository>
cd rsep
bin/setup

# Run tests
bundle exec rake test

# Check code style
bundle exec standardrb

# Run health checks
bundle exec rake health:check

# Demo application
cd test/dummy && bundle exec rails server

CI/CD

The project uses Forgejo CI with workflows in .forgejo/workflows/. CI runs automatically on pushes and pull requests, testing against Ruby 3.4 with Docker containers for consistent environments.

Contributing

  1. Fork the repository
  2. Create feature branch
  3. Make changes with tests
  4. Run bundle exec rake health:check
  5. Submit pull request

See GUIDE.md for detailed contribution guidelines.

License

GNU General Public License v3.0