Good idea. There's a few minor niggles, though: 1. Don't use `unsafeWindow`, this will break in Chrome and will not even work in Firefox+Greasemonkey if the effective `@grant` changes. 1. Avoid leading `*` wildcards in `@includes`, if you can help it. This is a big performance hit. `@match` limits the wildcard scope and performs much better and reports the sites/security correctly on Chrome. This gets all current SE sites: // @match http://*.askubuntu.com/questions/* // @match http://*.onstartups.com/questions/* // @match http://*.serverfault.com/questions/* // @match http://*.stackapps.com/questions/* // @match http://*.stackexchange.com/questions/* // @match http://*.stackoverflow.com/questions/* // @match http://*.superuser.com/questions/* 1. The regex `match` needs to be more robust, to account for all legal characters in the URL, and for anchors. 1. Use injection so that the script will work on most userscript-capable browsers (Chrome, Firefox, Opera, Safari, etc.). 1. Mathoverflow.net is not an SE site! Use [math.stackexchange.com][1] for that. mathoverflow.net also does not appear to support the *timeline* view/page. <br> Here's a variant of the script I've been using (It works on Chrome and Firefox, and should work on most other userscript-capable browsers): [**Easy install URL at GitHub**][2] for Greasemonkey, Tampermonkey, Scriptish, etc. // ==UserScript== // @name Add Timeline Button to Stack Exchange questions // @description Adds a "View Timeline" Button to Stack Exchange sites // @namespace StackExchange // @match http://*.askubuntu.com/questions/* // @match http://*.onstartups.com/questions/* // @match http://*.serverfault.com/questions/* // @match http://*.stackapps.com/questions/* // @match http://*.stackexchange.com/questions/* // @match http://*.stackoverflow.com/questions/* // @match http://*.superuser.com/questions/* // ==/UserScript== function addTimelineButton ($) { var buttonText = "View Timeline"; var timelineLink = "#"; var postNum = 0; var postMatch = location.pathname.match (/questions\/(\d+)\D/i); if (postMatch && postMatch.length > 1) { postNum = postMatch[1]; timelineLink = location.protocol + "//" + location.host + "/posts/" + postNum + "/timeline" ; } else { buttonText = "Path error 1"; } var targetNode = $(".favoritecount"); if (targetNode.length) { targetNode.after ('<a href="' + timelineLink + '">' + buttonText + '</a>'); } else if ( postNum && $("#content div.subheader > h1:contains('Page Not Found')").length == 0 ) { alert ("From Timeline script: Unexpected Page layout."); } } withPages_jQuery (addTimelineButton); function withPages_jQuery (NAMED_FunctionToRun) { //--- Use named functions for clarity and debugging... var funcText = NAMED_FunctionToRun.toString (); var funcName = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1"); var script = document.createElement ("script"); script.textContent = funcText + "\n\n"; script.textContent += 'jQuery(document).ready( function () {' + funcName + '(jQuery);} );'; document.body.appendChild (script); }; [1]: http://math.stackexchange.com/ [2]: https://gist.github.com/BrockA/5761948/raw/Add_Timeline_Button_to_Stack_Exchange_questions.user.js