Introduction
In this post, I will show you how to detect if a client has JavaScript enabled or disabled at your backend webserver (on any platform), so you can work with it in your backend code, and use it as a boolean.
Unfortunately, there is no out-of-the-box way to detect it. Browsers do not send http headers/metadata to the webserver that indicates if the browser has JavaScript turned on or off.
So to detect it, we need to do a little manual work.
How To Do It
Backend Code
The trick to detect it, is to set a flag (a cookie) in the client browser that indicates if the browser has JavaScript enabled/disabled.
Then the server can look at that cookie and check if JavaScript the client is indicating its JavaScript is enabled/disabled.
In this example, let's call that cookie hasjs=false.
So, if the client has the cookie named hasjs
and has the value false
, then it means the client is indicating that JavaScript is off
, otherwise JavaScript is on
.
So, for every webrequest
, make a boolean variable in your backend server, and call it IsJavascriptOn,
and set it to false
if client has the cookie hasjs=false
otherwise, set it to true
.
I will be using ASP.NET MVC as the code examples, but the concept is the same for all platforms.
Below is the example of a function that returns false
if the client has the cookie hasjs=false
, otherwise it returns true
.
bool GetIsJavascriptOn()
{
if (Request.Cookies.ContainsKey("hasjs") &&
Request.Cookies["hasjs"] == "false")
return false;
else
return true;
}
And then somewhere in our code, we can set our IsJavascriptOn
variable like below:
this.IsJavascriptOn = GetIsJavascriptOn();
And now, we have our boolean that determines if the client has JavaScript enabled/disabled, so now we can use this variable everywhere in our backendcode.
Rendering HTML
So now, we have need to set the hasjs=false
cookie if JavaScript is disabled, and delete the hasjs=false
cookie if JavaScript is enabled. And that's done when we render the HTML.
We have to render some HTML depending on whether the client is indicating that JavaScript is enabled/disabled. And that's shown below.
We will put this code inside the <head>:
@if (Model.IsJavascriptOn == true)
{
<noscript>
<meta http-equiv="Set-Cookie" content="hasjs=false; path=/">
<meta http-equiv="Refresh" content="0">
</noscript>
}
else //Client indicates javascript is disabled (cookie "hasjs=false" exists)
{
<script>
document.cookie = "hasjs=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
location.reload(true);
</script>
}
Now we are actually done. If you just want to test it and don't want any explanation, you can skip the rest.
Here, we draw the <noscript> block if our variable IsJavascriptOn
equals true
, otherwise we draw the <script>
block.
The <noscript>
block will set the cookie hasjs=false
and then refresh the page (yes, you can set a cookie and refresh the page without JavaScript).
The <script>
block will delete the cookie hasjs=false
and then refresh the page.
So what happens here, is if the client is indicating that JavaScript is on, then we draw the <noscript>
block. But the client will not run the <noscript>
block, unless it actually was disabled.
So if it runs the <noscript>
block, then it means the client told the server that it had JavaScript enabled, but was wrong, and needs to update/set the hasjs
to false
and then refresh the page.
Then after it has done that, the server will render the <script>
block instead, and then the client will never run the <script>
block until it enables it again.
So when the client enables JavaScript again, then the client will run the <script>
block, delete the cookie hasjs
and refresh the page.
And then, the server will draw the <noscript>
block and then the client will never run that block until the client disables JavaScript again.
And that's how the cycle goes.
Full Example with ASP.NET MVC
Here is a full example in ASP.NET Core MVC (.NET Framework). It's pretty straight-forward, so hopefully, non-ASP.NET programmers would understand it, since it's almost like pseudocode.
In this example, I will show a minimal website with 3 pages index (homepage
), contact and about with no CSS.
HomeController.cs
This file is the starting point of where the code begins when clients request a page on a specific path. It will check if the client has the hasjs=false
cookie and set our IsJavascriptOn
variable to false
if it exists, otherwise set it to true
.
using Microsoft.AspNetCore.Mvc;
namespace WebApplication1
{
public class ViewDataModel
{
public bool IsJavascriptOn;
}
}
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public ViewDataModel ViewDataModel;
bool GetIsJavascriptOn()
{
if (Request.Cookies.ContainsKey("hasjs") &&
Request.Cookies["hasjs"] == "false")
return false;
else
return true;
}
public IActionResult Index()
{
this.ViewDataModel = new ViewDataModel();
this.ViewDataModel.IsJavascriptOn = this.GetIsJavascriptOn();
return View(this.ViewDataModel);
}
public IActionResult About()
{
this.ViewDataModel = new ViewDataModel();
this.ViewDataModel.IsJavascriptOn = this.GetIsJavascriptOn();
return View(this.ViewDataModel);
}
public IActionResult Contact()
{
this.ViewDataModel = new ViewDataModel();
this.ViewDataModel.IsJavascriptOn = this.GetIsJavascriptOn();
return View(this.ViewDataModel);
}
}
}
_Layout.cshtml
This is the starting point when we render our HTML. The _Layout
is what gets rendered no matter what page we are on, and then it fires the @RenderBody()
which is an ASP.NET MVC function that will render the page we are on. And that's going to render in our case either the index.cshtml, contact.cshtml or about.cshtml.
@model ViewDataModel
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Detect_Javascript</title>
@if (Model.IsJavascriptOn == true)
{
<noscript>
<meta http-equiv="Set-Cookie" content="hasjs=false; path=/">
<meta http-equiv="Refresh" content="0">
</noscript>
}
else //Client indicates javascript is disabled (cookie "hasjs=false" exists)
{
<script>
document.cookie = "hasjs=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
location.reload(true);
</script>
}
</head>
<body>
<ul>
<li><a href="/home">Home</a></li>
<li><a href="/home/about">About</a></li>
<li><a href="/home/contact">Contact</a></li>
</ul>
@RenderBody()
</body>
</html>
Index.cshtml
@model ViewDataModel
<h1>Home page</h1>
<p>This is the home page</p>
@if (Model.IsJavascriptOn == true)
{
<p>Javascript is enabled</p>
}
else
{
<p>Javascript is disabled</p>
}
Contact.cshtml
@model ViewDataModel
<h1>Contact page</h1>
<p>This is the contact page</p>
@if (Model.IsJavascriptOn == true)
{
<p>Javascript is enabled</p>
}
else
{
<p>Javascript is disabled</p>
}
About.cshtml
@model ViewDataModel
<h1>About page</h1>
<p>This is the about page</p>
@if (Model.IsJavascriptOn == true)
{
<p>Javascript is enabled</p>
}
else
{
<p>Javascript is disabled</p>
}
So, here, if you do have JavaScript on, then it will draw Yes, javascript is enabled
otherwise, No, javascript is disabled
.
Below are two examples on how it should look:
Last Note
Inside the <noscript>
, the tag <meta http-equiv="Set-Cookie" content="hasjs=false; path=/">
, it's very important to set the path to "/"
, because cookies can have paths, so if you navigate to different paths/sites in the website, then the client might create many different hasjs=false
cookies depending on which path the client is on.
Thanks for reading, I hope this will be helpful to a lot of you. :-)