Easy Redesign in Rails: Run Old and New Side by Side with :variants.

Published on August 25, 2025
Written by Victor Cobos

Redesigning a mature Rails app can feel like a minefield. You're still pushing hotfixes to production, QA needs to validate existing behavior, and stakeholders want to compare the old and new versions side by side. Imagine being able to render both designs on the same page — safely, in the same app, with minimal code overhead and in production.

That’s where :variants come in.

What are Rails view :variants?

Most Rails developers know :variants as a way to serve different templates depending on device or context — like mobile vs. desktop. But the magic is that variants are format‑agnostic, so they can be used for any variation of a view.

Under the hood, when you use:

render variants: [:mobile, :desktop]

Rails will look for templates in this order:

• app/views/home/index.html+mobile.erb
• app/views/home/index.html+desktop.erb
• app/views/home/index.html.erb (fallback)

Perfect for device differences, sure — but it unlocks a more powerful use: design rollouts. You can add a +redesign version of your template, and Rails will choose it when request.variant = :redesign is set in your controller.

Because variants are supported throughout Rails, this approach works seamlessly with layouts, partials, mailers, and even ViewComponent templates. And since the logic for switching lives in a single place (setting request.variant), you avoid littering your views with scattered if statements or duplicating controller logic.

You might be tempted to toggle the redesign with a cookie, but for this use case I prefer using a simple URL parameter instead. By passing ?redesign=true on every internal link, you can keep the old and new design running in separate browser windows or tabs at the same time. That's incredibly useful during a redesign process, because QA testers, designers, or developers can compare both versions side by side without clearing cookies or switching accounts.

Rails makes this easy with default_url_options. You can override it in your controller (or ApplicationController) to automatically add the :redesign parameter whenever it's present in the request:

def default_url_options
  params[:redesign].present? ? {redesign: true} : {}
end

How to Wire Variants into Your Rails App

Instead of duplicating the variant-switching code in every controller, a cleaner approach is to extract it into a concern. This way you can include it wherever you need the redesign toggle, and keep the logic consistent across your app.

For example, create a concern in app/controllers/concerns/redesign.rb:

module Redesign
  extend ActiveSupport::Concern

  included do
    before_action :set_redesign_variant
  end

  private

  def default_url_options
    params[:redesign].present? ? {redesign: true} : {}
  end

  def set_redesign_variant
    if params[:redesign].present?
      request.variant = :redesign
    end
  end
end

You can then add this concern to any controller where you want redesign support: include Redesign.

With this setup, any request including ?redesign=true will automatically render the +redesign templates for that controller's views. The best part is that the logic lives in one place, making it easy to maintain and adjust later (e.g., feature flags, user-specific rollouts).

Full Support Across Rails Rendering Features

The great thing about variants is that they don’t just work with regular views. The same mechanism applies to layouts, partials, mailers, and even ViewComponent templates. That means you can keep both old and new versions cleanly separated without sprinkling conditional logic all over your code. Wherever Rails looks for a template, it also looks for the variant — giving you full coverage for a redesign, end to end.

Wrapping Up

The code examples in this post are meant as orientation — you'll likely need to adapt and refine them to fit your app. The key takeaway is that Rails variants are a powerful tool for handling redesigns. They let you keep old and new designs running in parallel, making it easier to test, compare, and roll out gradually.

In a real project, you’ll also want to think about who can access the redesign. Maybe you add a simple switcher in the UI, but only show it to specific users, or restrict it by office IPs. Feature flags and role checks are natural ways to manage that.

Finally, variants can even help you track your progress. By checking which views already have a +redesign template and which don’t, you can measure how much work is left before the old design can be retired.

Using :variants this way keeps your redesign process safe, transparent, and incremental — no more big-bang releases.

Subscribe to get future articles via the RSS feed .