Add Releases tab after Code tab on GitHub repos
// ==UserScript==
// @name Add GitHub Releases Tab
// @namespace https://github.com/nvbangg/nvbangg-tools
// @version 1.3
// @description Add Releases tab after Code tab on GitHub repos
// @author nvbangg (https://github.com/nvbangg)
// @copyright Copyright (c) 2026 Nguyễn Văn Bằng (nvbangg, github.com/nvbangg)
// @match https://github.com/*/*
// @icon https://github.com/favicon.ico
// @license MIT
// ==/UserScript==
(() => {
"use strict";
const ID = "releases-tab-link";
const TAG = `<path d="M1 7.775V2.75C1 1.784 1.784 1 2.75 1h5.025c.464 0 .91.184 1.238.513l6.25 6.25a1.75 1.75 0 0 1 0 2.474l-5.026 5.026a1.75 1.75 0 0 1-2.474 0l-6.25-6.25A1.752 1.752 0 0 1 1 7.775Zm1.5 0c0 .066.026.13.073.177l6.25 6.25a.25.25 0 0 0 .354 0l5.025-5.025a.25.25 0 0 0 0-.354l-6.25-6.25a.25.25 0 0 0-.177-.073H2.75a.25.25 0 0 0-.25.25ZM6 5a1 1 0 1 1 0 2 1 1 0 0 1 0-2Z"></path>`;
document.head.insertAdjacentHTML(
"beforeend",
`<style>@media (max-width:767px){#${ID} [data-component="text"],#${ID} [data-content]{display:none!important}}</style>`,
);
function addReleasesTab() {
const nav = document.querySelector('nav[aria-label="Repository"]');
if (!nav || nav.querySelector(`#${ID},a[href$="/releases"]`)) return;
const code = nav.querySelector('#code-tab,a[data-tab-item="code"]');
if (!code) return;
const item = code.closest("li") || code;
const clone = item.cloneNode(true);
const a = clone.matches("a") ? clone : clone.querySelector("a");
if (!a) return;
a.id = ID;
a.href = `${location.pathname.split("/").slice(0, 3).join("/")}/releases`;
a.ariaLabel = "Releases";
["aria-current", "data-hotkey", "data-react-nav", "data-react-nav-anchor"].forEach((k) => a.removeAttribute(k));
a.setAttribute("data-turbo-frame", "repo-content-turbo-frame");
const svg = a.querySelector("svg");
if (svg) svg.innerHTML = TAG;
const text = a.querySelector('[data-component="text"],[data-content]');
if (text) {
text.textContent = "Releases";
text.setAttribute("data-content", "Releases");
}
item.after(clone);
}
addReleasesTab();
new MutationObserver(addReleasesTab).observe(document.body, { childList: true, subtree: true });
})();