Adds multiple buttons to redirect from Google PlayStore to different websites. Uses native <a> links for long-press/right-click open, and auto-refreshes when app id changes.
// ==UserScript==
// @name PlayStore Redirect Buttons
// @namespace Multi-Redirect Buttons
// @version 2.6
// @description Adds multiple buttons to redirect from Google PlayStore to different websites. Uses native <a> links for long-press/right-click open, and auto-refreshes when app id changes.
// @match https://play.google.com/store/apps/details?id=*
// @icon https://www.google.com/s2/favicons?sz=64&domain=play.google.com
// @grant GM_addStyle
// ==/UserScript==
(function () {
'use strict';
// ---- Helpers ----
function getPackageId() {
const m = location.href.match(/[?&]id=([a-zA-Z0-9._-]+)/);
return m ? m[1] : null;
}
function addCSS() {
const css = `
.mr-buttons-container {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-top: 8px;
}
.mr-button {
color: #fff;
background: #555;
font-family: Roboto, Arial, sans-serif;
font-size: .9rem;
font-weight: 500;
height: 36px;
padding: 0 12px;
border-radius: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
transition: transform 0.2s, filter 0.2s;
text-decoration: none; /* anchor, styled like button */
cursor: pointer;
}
.mr-button:hover {
filter: brightness(0.85);
transform: translateY(-2px);
}
`;
if (!document.getElementById('mr-style')) {
const style = document.createElement('style');
style.id = 'mr-style';
style.textContent = css;
document.head.appendChild(style);
}
}
function findMount() {
// Prefer Install button area (Chromium placement), fallback to title (Firefox-friendly)
const installBtn = document.querySelector('button[aria-label^="Install"]');
if (installBtn) {
const mount = installBtn.closest('div');
if (mount) return mount;
}
const titleSpan = document.querySelector('h1 span');
if (titleSpan && titleSpan.parentElement) return titleSpan.parentElement;
return null;
}
// ---- Main injection ----
function insertButtons(pkgId) {
if (!pkgId) return false;
if (document.querySelector('.mr-buttons-container')) return true;
const parent = findMount();
if (!parent) return false;
addCSS();
const container = document.createElement('div');
container.className = 'mr-buttons-container';
container.setAttribute('data-pkg', pkgId);
parent.appendChild(container);
const buttons = [
{ text: 'A2zapk History', url: `https://a2zapk.io/History/${pkgId}/`, color: '#00875f' },
{ text: 'A2zapk Download', url: `https://a2zapk.io/apk/${pkgId}.html`, color: '#00875f' },
{ text: 'APKMirror', url: `https://www.apkmirror.com/?post_type=app_release&searchtype=apk&s=${pkgId}`, color: '#FF8B14' },
{ text: 'APKPure', url: `https://apkpure.com/search?q=${pkgId}`, color: '#24cd77' },
{ text: 'APKCombo', url: `https://apkcombo.com/search?q=${pkgId}`, color: '#286090' }
];
for (const b of buttons) {
const link = document.createElement('a');
link.textContent = b.text;
link.href = b.url;
link.target = '_blank'; // native new tab; enables long-press/right-click menus
link.rel = 'noopener'; // safety
link.className = 'mr-button';
link.style.backgroundColor = b.color;
container.appendChild(link);
}
return true;
}
function ensureButtons() {
const pkg = getPackageId();
let attempts = 0;
const maxAttempts = 20; // ~10s
const tryInject = () => {
attempts++;
if (insertButtons(pkg)) return; // success, stop retries
if (attempts < maxAttempts) setTimeout(tryInject, 500);
};
tryInject();
}
// ---- Initial load: keep observing until DOM settles ----
const observer = new MutationObserver(() => {
// Try to inject repeatedly as Play Store lazily builds the DOM
ensureButtons();
});
observer.observe(document.body, { childList: true, subtree: true });
// Run once on script start
ensureButtons();
// ---- Auto refresh when navigating between apps (id changes) ----
let lastPkg = getPackageId();
setInterval(() => {
const pkg = getPackageId();
if (pkg && lastPkg && pkg !== lastPkg) {
// Refresh once to force clean DOM rebuild and reliable placement
location.reload();
}
lastPkg = pkg || lastPkg;
}, 1000);
})();