Created
February 3, 2025 10:54
-
-
Save Cristiancastt/2fbf0b52152c3ebc5b903fce447fe1bf to your computer and use it in GitHub Desktop.
Medium Member script to inject a button that automatically redirect to free version of the original post
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Medium to Freedium Redirect with Button | |
// @namespace http://tampermonkey.net/ | |
// @version 2024-09-23 | |
// @description Insert a button to redirect Medium posts to an alternative free version. | |
// @author Cristiancast - https://github.com/Cristiancastt | |
// @match https://medium.com/* | |
// @match https://*.medium.com/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=medium.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// Function to create and insert the button | |
function insertRedirectButton() { | |
// Remove existing button if present | |
const existingButton = document.querySelector('.freedium-redirect-button'); | |
if (existingButton) existingButton.remove(); | |
const button = document.createElement('button'); | |
button.className = 'freedium-redirect-button'; | |
button.textContent = 'Read on Freedium'; | |
// Apply button styles | |
const style = document.createElement('style'); | |
style.textContent = ` | |
.freedium-redirect-button { | |
appearance: none; | |
background-color: #2ea44f; | |
border: 1px solid rgba(27, 31, 35, .15); | |
border-radius: 6px; | |
box-shadow: rgba(27, 31, 35, .1) 0 1px 0; | |
box-sizing: border-box; | |
color: #fff; | |
cursor: pointer; | |
display: block !important; | |
font-family: -apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif; | |
font-size: 14px; | |
font-weight: 600; | |
line-height: 20px; | |
margin: 10px; | |
padding: 6px 16px; | |
position: fixed; | |
top: 60px; | |
right: 20px; | |
text-align: center; | |
user-select: none; | |
z-index: 999999; | |
opacity: 1 !important; | |
visibility: visible !important; | |
} | |
.freedium-redirect-button:hover { | |
background-color: #2c974b; | |
} | |
.freedium-redirect-button:focus { | |
box-shadow: rgba(46, 164, 79, .4) 0 0 0 3px; | |
outline: none; | |
} | |
.freedium-redirect-button:active { | |
background-color: #298e46; | |
} | |
`; | |
// Ensure style is added only once | |
if (!document.head.querySelector('style[data-freedium-styles]')) { | |
style.setAttribute('data-freedium-styles', 'true'); | |
document.head.appendChild(style); | |
} | |
// Add click event to redirect to freedium | |
button.addEventListener('click', function() { | |
const currentUrl = window.location.href; | |
let freediumUrl; | |
// Check if URL contains subdomain.medium.com pattern | |
if (currentUrl.match(/https:\/\/[^.]+\.medium\.com\//)) { | |
// Remove the subdomain part and replace medium.com with freedium.cfd | |
freediumUrl = currentUrl.replace(/https:\/\/[^.]+\.medium\.com\//, 'https://freedium.cfd/'); | |
} else { | |
// For regular medium.com URLs | |
freediumUrl = currentUrl.replace('medium.com', 'freedium.cfd'); | |
} | |
window.location.href = freediumUrl; | |
}); | |
// Insert the button into the body | |
document.body.appendChild(button); | |
} | |
// Function to check if we're on a Medium page | |
function isMediumPage() { | |
return window.location.hostname.includes('medium.com'); | |
} | |
// Function to initialize the button | |
function init() { | |
if (isMediumPage()) { | |
// Small delay to ensure the DOM is ready | |
setTimeout(insertRedirectButton, 1000); | |
} | |
} | |
// Run on initial page load | |
init(); | |
// Create a more robust observer for SPA navigation | |
let lastUrl = location.href; | |
new MutationObserver(() => { | |
const url = location.href; | |
if (url !== lastUrl) { | |
lastUrl = url; | |
init(); | |
} | |
}).observe(document, { subtree: true, childList: true }); | |
// Also check periodically in case the observer misses something | |
setInterval(init, 5000); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment