On a recent Rails project, I was asked to verify if the visiting user's browser has cookies enabled, and display a message on top of the screen if they don't. While I don't want to get into the reasoning why, or get into a flame war whether the site should still be accessible regardless if the user's browser has cookies, I still needed to implement it.

Since it's a Rails project, I thought of checking if the session cookie that Rails sets in the Application controller was set. But Rails sets the session after the view is rendered the first time (I have a more detailed explanation somewhere but don't have it with me, so maybe next time). This means the first time the user visits the site, it will incorrectly display the warning message. Subsequent views will test correctly, but this obviously won't work.

So I decided to implement a redirect, thanks to ideas given by this blog post. It worked, but it left me with a parameter in my URL the first time the user visited the site. It didn't seem clean, and the higher-ups didn't like it either, so off it went.

Then I was given the idea to check it via JavaScript, and with some slight tinkering I think I got what I wanted:

Basically this uses JavaScript to set the cookie when the page is rendering and immediately checks for its availability using a regular expression. If it's found, then the user has cookies enabled and we can safely delete the test cookie (provided the user has their system clock set after January 1, 2001). If the cookie isn't set, that means the user doesn't have cookies enabled in their browser, so we display the 'cookies_disabled' element with our message inside.

This function is called in our application layout, between the <head> tags, meaning it's called for every single page that renders the default layout. I haven't observed any type of performance issue this might have, but I might have missed something along the way. And there's probably a better, more efficient way to handle this as well, so if you have any suggestions, feel free to dtop a comment and let me know.