Classic Stats Redirect script v2 released!

Version 2.0.0 of my classic stats redirect script is out! I had actually released it on Thursday, but I didn’t get a chance to write this post until now. If you have auto-updating enabled for the script, which is the default, you should have already received the update. Otherwise, you can head over to Greasy Fork to install it manually. This new version redirects instead to the classic dashboard stats page. Thanks goes to PiedType for alerting me of the problem and to Dennis for the idea for the solution.

If you would prefer to use the new stats page and would like to use your screen space a little more, you can install my stylesheet that does that.

If you’d like to learn more about how the script works, keep reading. Otherwise, you can stop here and enjoy your classic stats! Leave a comment if you have any trouble setting it up or if you have any questions.


WordPress.com staff warned us about the deprecation of the old stats page last year, and as of yesterday, it’s now gone. My stats redirect script broke as a result, causing a redirect loop. I would have liked at least a notice the day before they were going to take it down, but I didn’t expect anything given their record of not informing us of things beforehand.

To solve this, I had to first check to see what kind of redirect was happening. If it was a JavaScript redirect, there might have been a way around it. If it was a server-side redirect, the page was probably gone for good. To check, I exported my cookies and did a HEAD request. This was the output:

$ curl -b cookies.txt -I https://wordpress.com/my-stats      
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Thu, 22 Dec 2016 00:59:39 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
X-hacker: If you're reading this, you should visit automattic.com/jobs and apply to join the fun, mention this header.
X-Frame-Options: SAMEORIGIN
Location: https://wordpress.com/stats
X-ac: 2.ewr _dca
Strict-Transport-Security: max-age=15552000; preload

The important part is the first line of the output: HTTP/1.1 301 Moved Permanently. As the description suggests, this means that the page at the URL is a permanent redirect to the URL given by the Location header which in this case is https://wordpress.com/stats.

As I feared, it was a server-side redirect. There is a very slim chance in which appending a certain query variable to the URL would prevent a redirect, but I was not optimistic and I would have no effective way of guessing what that would be. In any case, a hotfix needed to be pushed out as quickly as possible to prevent the infinite redirect from happening. I decided the best hotfix would be to disable the functionality altogether, because no redirect is better than a redirect loop.

Commit 0399840 implemented the hotfix, which was to return control before any of the redirect code ran.

// @run-at document-start
// ==/UserScript==

// The old stats page has been taken offline.
// Until a fix can be made (if that's even possible),
// return early to prevent an infinite redirect
return;

var parsedUrl=window.location.pathname.match(/stats(\/([^\/]*))?/);
var blogDomain=parsedUrl[2];

I was ready to make my script obsolete when Dennis suggested that I make it redirect to the classic dashboard stats page instead.

The approach I settled on was similar to the approach that the editor redirect script takes: attempt to get the blog URL from the API and fall back to the blog domain in the URL if the API returned an error (e.g. for private blogs), then use that to build . Using the domain would work for WordPress.com sites, but it isn’t guaranteed to work with Jetpack-enabled sites, so the API is called first to get a more precise URL. Ideally, I’d have the API call be authenticated so that I would be able to get the wp-admin URL directly, but I still haven’t figured out authentication yet. If a blog domain isn’t found in the URL, then the redirect is aborted.

if (blogDomain) {
  // Redirect to post URL based on API results
  // API docs: https://developer.wordpress.com/docs/api/
  fetchJSONFile("https://public-api.wordpress.com/rest/v1.1/sites/" + blogDomain,
    // attempt to redirect using API
    function(data) {
      redirectToClassicStats(data.URL);
    },

    // fallback: attempt to use the blog domain
    function() {
      // use http instead of https in case the server doesn't support https
      // (e.g. for Jetpack sites)
      redirectToClassicStats('http://' + blogDomain);
    }
  );
}

The regular expression I use to parse the initial URL breaks it up into two parts: the stats type, and the blog domain.

var parsedUrl = window.location.pathname.match(/stats\/(insights|day|week|month|year)(?:\/([^\/]*))?/);
var statsType = parsedUrl[1];
var blogDomain = parsedUrl[2];

EDIT 2016-12-25: This regex is incomplete. v2.0.1 makes the stats type optional.

The stats type can be one of “insights”, “day”, “week”, “month”, or “year”, and of those, “day”, “week” and “year” map directly to tabs in the classic stats page. Here’s the redirect code:

function redirectToClassicStats(baseUrl) {
  var query = ["page=stats"];

  switch (statsType) {
    case "day":
      query.push("unit=1");
      break;
    case "week":
      query.push("unit=7");
      break;
    case "month":
      query.push("unit=31");
      break;
  }

  window.location.replace(baseUrl + '/wp-admin/index.php?' + query.join("&"));
}

This function takes in the base URL, which is either from the API or constructed using the domain as appropriate. It adds the stats type to the query part of the URL (the part that goes after the ?) if it can, then builds the URL based on the base URL and the query part.

Taking this site as an example, if I went to go check my weekly stats at https://wordpress.com/stats/week/tpenguinltg.wordpress.com, the parser would recognize that the stats type is week and the blog domain is tpenguinltg.wordpress.com. The script will then call the API and the API will return with https://tpenguinltg.wordpress.com. The code then builds the redirect URL based on the URL returned by the API and the stats type, giving https://tpenguinltg.wordpress.com/wp-admin/index.php?page=stats&unit=7. The script then redirects to that constructed URL, giving me the classic dashboard stats.

Up next is version 2.1.0. In that version, I plan to support redirecting when there is no blog domain (e.g. for /stats, /stats/insights, /stats/day, etc.). This will probably be done by scraping the page for the first blog, which is always your main blog. This will also get around the bug caused by the JavaScript navigation that the new stats uses in which navigating to another stats page using links in the new stats page does not redirect, even if the URL would normally be matched.

20 comments
  1. Dennis said:

    I tested the script and in my case version 2 is not redirecting. I thought I have to restart Firefox, or that the script was not enabled, or GreaseMonkey. I checked all that but everything is fine except that the script does not redirect.

    I am glad that you keep this script updated, can’t thank you enough. I wish you happy holidays!

    • What’s the first URL you visit? There are a few cases where the redirect doesn’t work. In particular, it doesn’t work if you don’t have a domain at the end of the URL (this fix is planned for v2.1, which will probably be released after the holidays), and if you try to navigate using the links new stats page (the redirect only works on the first visit because of all the JavaScript used by the page; I’m not sure how to fix this yet).

      Happy holidays to you, too!

      • Dennis said:

        From the dashboard I click on the 48h graph or the “view all” stats link. It’s https://wordpress.com/stats/mydomainname but then it loads https://wordpress.com/stats/insights/mydomainname and it goes to the new stats page.

        Also by the way, can you suggest a CSS and javascript online course? Did you have a favorite one or how did you learn it? Or did you prefer books? I have a bit of basic knowledge about programming. I mean I know what functions are, variables and strings and basic syntax: I played a bit with Visual Basic back then and created basic programs with loops, if then else and so. Recently I looked into a C++ Udemy course and finished the basic syntax lection and understood this well due to my previous Visual Basic experience. But I hearthis language is a bit over the top because of memory management and so. For small games people suggested C# is easier to learn.

        But then there is also the online stuff, Greasemonkey and Stylish. What you do here is awesome. I like the idea that you can customize your online experience with CSS and javascript. I’d like to take a look into it, because I visit other sites where I think the “usability” could be improved, it’s just that I don’t have CSS and javascript knowledge yet :) Also I realized, as webmaster it probably makes much more sense to learn CSS and javascript, especially because I probably wouldn’t ever finish to code a desktop application or a game anyway with C# or C++ (laugh).

        Since I browse the web a lot, javascript and CSS would do a better job to fill my personal and simple needs, or to solve problems. In other words, I would actually have ideas and could try to program code that I actually would use myself daily with my browser. And maybe the knowledge would also be handy for future online projects.

      • Ah, I see the problem. My regex is wrong. I’ll push up a fix soon.

        As for a good online course, after reading a book on Netscape and HTML that was published in 1995 (extremely out of date now, but it’s interesting to see how things differed back then), I learned on W3 Schools. As much as I still somewhat hesitate to recommend it, it’s gotten better now and as long you follow up with other resources, it’s a decent place to start. I would recommend learning HTML first, because without knowing HTML, trying to learn JavaScript and CSS for the Web will be very difficult. I encourage you to pursue this interest as it’s very useful and rewarding to able to do the things you described.

      • Alright, I’ve just pushed v2.0.1 which should fix your problem. You can get it with the usual methods. Let me know if you have any issues with it.

      • Dennis said:

        Thanks, reinstalled the fixed version and it works now! Over the next days I will also try your stylesheet, because I believe the new stats page is on a right way, it just should have more width and I see this is what your stylesheet solves. After that I make a decision which method I prefer.

      • Glad to hear it! I still haven’t decided which stats page I prefer, because while there are lots of things that annoy me about the new stats page, the classic stats doesn’t have visitor information. If I can figure out how to authenticate properly with the API, that’s something that I could probably add to the classic stats.

      • Dennis said:

        Yes. currently we are in a situation where both pages and advantages and disadvantages. In the news stats screen I do for example miss the summaries table where you can see detailed data and percentage swings, but that’s just one problem.

        Maybe they can answer your question in the forum thread, I hope they will answer after the holidays.

      • Dennis said:

        I believe I have a basic foundation with HTML too, although I wouldn’t be able to design a page from scratch. Looks like I have always been the guy who learned a bit here and there from snippets and so (laugh). I just understand some things when I go through HTML files, but I guess it would still make sense to expand my knowledge with HTML and to really focus on it. I remember the W3 school site, I used this one when I had a German selfhosted project where I wanted to edit some HTML files back then.

        Thanks for encouraging me, I see why this is very rewarding. I have already so many interests, like guitar playing, photography, blogging but I’d like to make some room to learn scripting, because this is indeed very useful too. I strongly believe that the ability to create things is an asset. :)

        And thanks for the coming fix :)

  2. Thanks, Penquin. But after poking around for a while I decided there were some features retained in the new stats, namely the bar graph with both views and visits, that I really want to see, while everything else on the old, old stats page is better. So I’ve bookmarked both. What apparently has been deleted by WP is the stats page that immediately preceded this newest one. THAT’s the one I most want back.

    Thanks so much for all you do for the community. Hope your holidays are memorable.

    • Yes, the only thing I miss from the old stats that’s not available in the classic stats was the distinction between views and visits, so I’m still not decided on whether I’ll be using this script or not. I hope your holidays are memorable, too!

    • No problem at all! I hope you’re enjoying the holidays.

`$name' says...

This site uses Akismet to reduce spam. Learn how your comment data is processed.