# thoughtbot/high_voltage: Static Pages as Rails Views, Without a CMS

> High Voltage is a Rails engine that maps URLs to templates in app/views/pages. It is small, in maintenance mode, and only worth adopting if static pages really are static.

**thoughtbot/high_voltage** — Easily include static pages in your Rails app.

- Repository: https://github.com/thoughtbot/high_voltage
- Website: http://thoughtbot.github.io/high_voltage
- Stars: 3,234 · Forks: 148
- Language: Ruby
- License: MIT
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/thoughtbot-high-voltage

## The problem High Voltage solves, and the kind of team it fits

A Rails application accumulates pages that are not resources. About us. Directions. A pricing page. Terms. They have no model, no database table, no controller worth writing, and no state. The usual answers are a CMS, a static site generator bolted on beside the Rails app, or a hand-written controller per page. High Voltage takes a fourth route: it is a Rails engine that treats each static page as a view template under app/views/pages and routes to it by filename.

The README is explicit about the audience. Static pages are, in its words, "like 'About us', 'Directions', marketing pages, etc." That is the whole scope. If your pages are edited by non-developers, this is the wrong tool, because there is no admin interface and no content store. If your pages are ERB files that ship with a deploy, the engine removes a controller and a route line from your codebase.

The repository carries a maintenance-mode note: the maintainers say they are not actively adding features, but will fix bugs and keep it compatible with current Ruby and Rails versions. The last push was on 2026-06-22, so the project is still being touched, but the stated intent is compatibility rather than new capability. Plan for a dependency that stays still.

## How the engine maps a URL to a template

High Voltage is a Rails engine, and the repository layout reflects that: app/, config/, lib/ and spec/ sit at the top level alongside the gemspec. The engine draws routes by default, so a request for /pages/about resolves to the show action with an :id of about, and the controller renders app/views/pages/about.html.erb through the normal Rails view lookup. There is no database query and no model layer.

The default URL shape is /pages/:id, where :id is the view filename. Nested directories are supported, so page_path('about/corporate/policies/HR/en_US/biz/sales/Quarter-Four') resolves against a matching directory tree under app/views/pages. The README gives that exact example, and it is worth noting that nothing in the engine limits how deep you go. A deep tree is a design decision you make, not one the gem makes for you.

Routing is configurable in three directions the README documents. You can move a page to a different URL by routing to the show action with an explicit :id, which is how you would put a page at /pages/home or at the root. You can drop the pages prefix entirely by setting config.route_drawer to HighVoltage::RouteDrawers::Root, which turns /about into a top-level path. Or you can set config.routes to false and define your own routes against the engine's controller. The engine also exposes HighVoltage.page_ids, a list of the page identifiers, which the README suggests feeding into sitemap_generator with a monthly changefreq.

## Installing high_voltage and serving your first page

The README gives two installation paths. A standalone install is a single gem command; in an application you add the gem to your Gemfile. The README's Gemfile example pins the 5.0.0 series, so check the gemspec and your Rails version before copying it verbatim.

```ruby
gem 'high_voltage', '~> 5.0.0'
```

After bundling, create the pages directory and a template. The README uses about.html.erb as the example, and the file has to live under app/views/pages for the default routing to find it.

```bash
mkdir app/views/pages
touch app/views/pages/about.html.erb
```

Put something in the template, then link to it with the named route the engine generates. The helper is page_path, and the argument is the filename without its extension.

```ruby
<%= link_to 'About', page_path('about') %>
```

At this point a request to /pages/about should render your template. If you want that page at the site root instead, the README shows an initializer setting config.home_page to 'home', which renders app/views/pages/home.html.erb for / and issues a 301 redirect from /home to / so search engines see one canonical URL. To remove the pages segment from every URL, set the route drawer to HighVoltage::RouteDrawers::Root in the same initializer.

## Overriding the controller when static is not enough

The engine's default controller is deliberately plain, and the README lists the four reasons you would replace it: you need authentication around the pages, you need different layouts per page, you need to render a partial from app/views/pages, or you have your own Page resource and want to keep High Voltage's StaticPage resource separate.

The documented path is to generate your own controller, set config.routes to false, and define the route yourself with a wildcard id. The README's route is get "/pages/*id" => 'pages#show', as: :page, format: false, and it notes that if you route the root path you should update the root line to point at your controller with id: 'home'. Your controller then includes HighVoltage::StaticPage, which is the concern that supplies the page-finding behaviour. From there you can add a before_action for authentication or a layout method that switches on params[:id].

There is a second extension point below that. The page_finder_factory method can be overridden to change how a page is located, and the README's example names a Rot13PageFinder. The README shows the method signature and stops there; it does not show the finder class itself, so you are writing that part from the StaticPage concern's expectations rather than from a worked example.

One naming constraint is easy to miss. High Voltage generates a named route called page_path, and the README warns that if you define your own route with the :as option, you must not use :page, because it will conflict.

## Where High Voltage stops being the right answer

The most consequential limitation is that the engine has no content storage. A page is a file in your repository. Changing the wording of your pricing page means a commit, a review and a deploy. Teams that expect a marketing colleague to edit copy will find nothing here for them, and no amount of configuration changes that, because the design has no database layer at all.

Caching is the second gap, and it is a removal rather than an omission. The README states that built-in caching support has been removed, pointing at PR 221, and directs you to the Rails caching guide instead. If you were relying on page caching from an older version, that behaviour is gone and you will be wiring it yourself, either through Rails caching or by overriding the controller.

There is also a routing subtlety worth understanding before you adopt the Root route drawer. Removing the pages prefix means your static pages now occupy the top level of the URL space, where they can collide with real application routes. The README presents the Root drawer as a configuration switch and does not discuss collision handling, so route ordering is your responsibility.

Finally, the maintenance-mode note matters for planning. The maintainers commit to bug fixes and compatibility with current Ruby and Rails, not to new features. If your requirements include anything the current version does not do, the realistic answer is to build it in your own controller rather than wait for it upstream.

## High Voltage compared with a CMS or a static site generator

The closest alternative in spirit is a Rails CMS such as Refinery or a database-backed page model you write yourself. The difference is where the content lives. A CMS stores page bodies in the database and renders them through an admin interface, which buys you editing without a deploy and costs you a schema, a migration path and an admin surface to secure. High Voltage stores page bodies as ERB templates in app/views/pages, which buys you version control, code review and the full Rails view stack (partials, helpers, content_for) and costs you the ability to change copy without shipping code.

A static site generator is the other direction. It builds HTML ahead of time and serves it without Rails in the request path, which is faster and removes the application from the equation entirely. High Voltage keeps the request inside Rails, which means your pages can use the application layout, your helpers and your authentication. That is the trade: you keep Rails, and you accept Rails as a dependency for pages that have no dynamic content.

If what you actually want is a page model with a title, a slug and a body that an editor can change, none of these three is a drop-in for the others, and High Voltage is the one that assumes the content is code.

## Maintenance cost, upgrades and the MIT licence

The upgrade surface is small because the engine is small. Releases are infrequent: the README's Gemfile example targets the 5.0.0 series, and the release history shows v4.0.0 in May 2024, a 4.0.0.rc1 before it, and v3.1.2 back in 2019. A major version bump between 3.x and 4.x is the kind of change that can require route or configuration edits, so read the CHANGELOG.md at the repository root before moving across a major boundary. The repository also carries Appraisals and a gemfiles/ directory, which is the project's own mechanism for testing against multiple Rails versions; that is a signal about what the maintainers test, not a guarantee about your combination.

The licence is MIT, per the MIT-LICENSE file at the repository root. MIT is permissive: it allows use, modification and redistribution with the licence and copyright notice retained. That is a description of the licence text, not legal advice, and if your organisation has rules about attribution or about vendoring dependencies, the file to read is MIT-LICENSE.

Security reporting is covered by SECURITY.md at the root, and CODEOWNERS and CONTRIBUTING.md indicate a maintained contribution process even under the maintenance-mode note. For a dependency of this size, the practical cost is the Rails version matrix rather than the gem itself.

## Conclusion

Adopt high_voltage if your About, Directions and marketing pages are ERB templates that change with a deploy, and you want them routed through Rails rather than a separate static host. Do not adopt it if editors need to change copy without a developer, if you need per-page caching out of the box, or if the pages are not Rails views at all. Before committing, check the 5.0.0 requirement in the gemspec against your Rails version, confirm whether you want the default /pages/:id routes or the Root route drawer, and read the override section if you need authentication or per-page layouts.

## FAQ

### What is high_voltage in Rails?

It is a Rails engine for static pages, described in its README as covering pages "like 'About us', 'Directions', marketing pages, etc." It routes a URL to a template under app/views/pages rather than to a database-backed record.

### How do I install high_voltage?

Either run gem install high_voltage, or add gem 'high_voltage', '~> 5.0.0' to your Gemfile as the README shows. Then create app/views/pages and add your first template there.

### How do I link to a high_voltage page?

The engine generates a page_path helper. The README's example is <%= link_to 'About', page_path('about') %>, where the argument is the view filename without its extension.

### Does high_voltage support caching?

Not built in. The README states that built-in caching support has been removed, referencing PR 221, and points to the Rails caching guide for page and action caching instead.

### Is high_voltage still maintained?

The README says the project is in maintenance mode: no new features are being added, but bugs are fixed and compatibility with current Ruby and Rails versions is kept. The last push to the repository was on 2026-06-22.

## Sources

- [License: MIT](https://github.com/thoughtbot/high_voltage/blob/main/LICENSE)
- [Project website](http://thoughtbot.github.io/high_voltage)
- [README](https://github.com/thoughtbot/high_voltage/blob/main/README.md)
- [Releases](https://github.com/thoughtbot/high_voltage/releases)
- [thoughtbot/high_voltage on GitHub](https://github.com/thoughtbot/high_voltage)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/thoughtbot-high-voltage
