DEV Community

loading...
Cover image for Dark mode in Ruby on Rails with cookies

Dark mode in Ruby on Rails with cookies

sylwiavargas profile image Sylwia Vargas ・2 min read

If you are building a Rails app and for the sake of practice try not to use JS, here is a recipe for adding a dark mode to your website using cookies.


Step 1: in the Application Controller set up cookies

We first set cookies and then redirect the user to a page. In our case, if a user is logged in, they will be redirected to their landing page and otherwise, to the welcome screen:

def moon
  cookies[:moon] = {
    value: 'dark mode on'
  }
  if @logged_in_user
    redirect_to user_stories_path
  else
    redirect_to welcome_index_path
  end
end
Enter fullscreen mode Exit fullscreen mode

Although the light mode is the default one, we also set a method for it so that the user can switch the dark mode off:

def sun
  cookies.delete(:moon)
  if @logged_in_user
    redirect_to story_books_path
  else
    redirect_to welcome_index_path
  end
end
Enter fullscreen mode Exit fullscreen mode

Step 2: Create routes

Now, in the config/routes.rb create routes for these two methods. You’ll need the routes later.

get '/moon', to: 'application#moon', as: 'moon'
get '/sun', to: 'application#sun', as: 'sun'
Enter fullscreen mode Exit fullscreen mode

Step 3: Enable page to check cookies

In the app/views/layouts/application.html.erb, in the <head> I introduced the following code to first check whether cookies are on, and if so — to load an appropriate stylesheet:

<head>
      <title> ✨ Fierce Stories ✨ </title>
      <%= csrf_meta_tags %>
      <%= csp_meta_tag %>
      <link rel="icon" href="https://upload.wikimedia.org/wikipedia/en/d/d6/Official_Logo_OneLove.png">

  <% if cookies[:moon] %>
      <%= stylesheet_link_tag 'application_dark', media: 'all', 'data-turbolinks-track': 'reload' %>
  <% else %>
      <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
  <% end %>

  <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
Enter fullscreen mode Exit fullscreen mode

Step 4: Add buttons to switch Dark Mode on/off

In our header, we have a Dark Mode/Light Mode button. The code for it looks as following:

<% if cookies[:moon] %>
<%= button_to 'Light Mode', sun_path, method: :get%>
<% else %>
<%= button_to 'Dark Mode', moon_path, method: :get%>
<% end %>
Enter fullscreen mode Exit fullscreen mode

note: You need a method: :get because that’s not what the buttons default to.

Step 5: Create the Dark Stylesheet

In app/assets/stylesheets duplicate your basic stylesheet and change colors where appropriate.


Photo by Sam Kolder from Pexels

Discussion

pic
Editor guide
Collapse
yaro_the_slav profile image
Yaroslav Shmarov

Good, however I think students at Yale deserve a better way to set light/dark😉

  • 1) The approach above does not work with Rails 6 and Webpacker.
  • 2) The approach above doesn't need a separate action for moon and sun, as well you don't need to use routes at all for cookies. I would make it shorter:
# application.html.erb

<% if cookies[:theme] == "light" %>
  <%= link_to "go dark", root_path(theme: "dark") %>
<% else %>
  <%= link_to "go light", root_path(theme: "light") %>
<% end %>
Enter fullscreen mode Exit fullscreen mode
# application_controller.rb

before_action :set_theme

def set_theme
  if params[:theme].present?
    theme = params[:theme].to_sym
    cookies[:theme] = theme
    redirect_to root_path
  end
end
Enter fullscreen mode Exit fullscreen mode

And for setting backgrounds, you don't need to have a lot of stylesheet files. Just use css variables:

# application.html.erb
  <body class="<%= cookies[:theme] %>">
Enter fullscreen mode Exit fullscreen mode
# application.scss
body.light {
  background-color: #f8f0e6;
}
body.dark {
  background-color: #1f2c44;
}
Enter fullscreen mode Exit fullscreen mode

Source: blog.corsego.com/ruby-on-rails-dar...

Collapse
didin1453fatih profile image
Info Comment marked as low quality/non-constructive by the community. View code of conduct
Didin 👨‍💻

I think you can combine Rails and dbdesigner.id as your database designer. This can make your project readable and clear documentation.

Collapse
sylwiavargas profile image
Sylwia Vargas Author

Thank you for your comment — dbdesigner.id looks interesting. Can you tell me how it relates to what I wrote?

Collapse
didin1453fatih profile image
Didin 👨‍💻

I just give you an information about it. I hope this can helped your work...