Skip to content

Instantly share code, notes, and snippets.

@mathix420
Last active July 7, 2025 14:29
Show Gist options
  • Save mathix420/e0604ab0e916622972372711d2829555 to your computer and use it in GitHub Desktop.
Save mathix420/e0604ab0e916622972372711d2829555 to your computer and use it in GitHub Desktop.
Bypass Medium Paywall - Working late 2023 - Greasy Fork, Violentmonkey, Tampermonkey - Click the RAW button to install
// ==UserScript==
// @name Medium Paywall Bypass
// @namespace Violentmonkey Scripts
// @run-at document-start
// @match *://*.medium.com/*
// @match *://medium.com/*
// @match *://*/*
// @grant none
// @version 2.4
// @inject-into content
// @updateURL https://gist.githubusercontent.com/mathix420/e0604ab0e916622972372711d2829555/raw/medium.user.js
// @downloadURL https://gist.githubusercontent.com/mathix420/e0604ab0e916622972372711d2829555/raw/medium.user.js
// @website https://freedium.cfd
// @author Mathix420, ZhymabekRoman
// @description Don't forget to remove `@match` filters you don't want.
// ==/UserScript==
// initCall is telling us if we need to inject the title observer
function mediumRedirecter(initCall = false) {
if (
// Allow seeing original articles that were already redirected to freedium.
!window.location.href.endsWith('#bypass') &&
// Do not redirect when editing on medium.
!window.location.href.includes("/edit?source=") &&
// Detect if we are on a medium website (regardless of the domain)
document.head?.querySelector('meta[property="al:android:url"]')?.content?.includes('medium://p/')
) {
window.location.href = 'https://freedium.cfd/' + window.location.href;
} else if (initCall && /(.*\.|^)medium\.com$/.test(window.location.host)) {
// Observe <title> changes
new MutationObserver(function(mutations) {
// If title change is detected, check if a freedium redirect is required
if (mutations[0].target.textContent) mediumRedirecter();
}).observe(
document.querySelector('title'),
{ subtree: true, characterData: true, childList: true }
);
}
}
mediumRedirecter(true);
@rodolfogoulart
Copy link

Can you remove? // @match *://*/*

do not make sense to be for all sites.

@ZhymabekRoman
Copy link

do not make sense to be for all sites.

Medium has too many sub-domains

@a-pav
Copy link

a-pav commented Apr 25, 2024

Medium has too many sub-domains

// @match *://*.medium.com/* Should be enough for matching sub-domains.

@ZhymabekRoman
Copy link

Should be enough for matching sub-domains.

What about devopsquare.com, blog.devops.dev, blog.stackademic.com, ai.plainenglish.io, bettermarketing.pub and etc? It's impossible for us to say how many Medium sites there are.

@a-pav
Copy link

a-pav commented Apr 25, 2024

You are right. I didn't know those type of sites exist. But they are just different domains, technically speaking.

To recap:
// @match *://*.medium.com/* Is enough for matching sub-domains.
// @match *://*/* Is needed for matching any possible domain who happens to be a Medium website.

@yluom
Copy link

yluom commented Apr 26, 2024

freedium is offline so unfortunately this script doesn't work anymore for now

@ZhymabekRoman
Copy link

All works as expected. Yeah, we made some codebase refactor, to improve speed and some big bug fixes. And there were some minor downtimes.

@mathix420
Copy link
Author

mathix420 commented May 14, 2024

Thanks @a-pav I wasn't aware that optional chaining was supported on tampermonkey. Yes, the mutationobserver is being registered, try commenting the section and click a link in this page for example https://medium.com/@francais you'll notice no redirect.

@rjmsilveira
Copy link

What a wonderful script. Thank you for sharing 🙇

@zzJinux
Copy link

zzJinux commented Jul 16, 2024

In case freedium goes unstable, how about disabling redirects for free posts? This is the predicate to check if it is a premium content: document.querySelector('.meteredContent') != null

@mathix420
Copy link
Author

@zzJinux yes, I thought about that too a couple months ago, I will try to implement it once I have more free time

@zzJinux
Copy link

zzJinux commented Jul 16, 2024

@mathix420 I have already locally patched the script to add the predicate. I hope your version will do so.

@mathix420
Copy link
Author

@zzJinux if you want you can fork this gist and update it so I can replicate your changes

@zzJinux
Copy link

zzJinux commented Jul 18, 2024

@mathix420 Just a few lines change: https://gist.github.com/zzJinux/364725e7c61810719286d94e88a4e38c I haven't had any issues.

@ZhymabekRoman
Copy link

Guys, sorry, yeah I known that's my fault. I need your help: Freedium-cfd/web#16 (comment)

@vgeorgiev69
Copy link

vgeorgiev69 commented Jul 6, 2025

Not sure if I'm doing something wrong, but the above script doesn't work as of the time of writing (at least in Firefox). This works though:

// ==UserScript==
// @name        Medium Paywall Bypass
// @namespace   Violentmonkey Scripts
// @run-at      document-idle
// @match       *://*.medium.com/*
// @grant       none
// @version     2.5
// @author      Mathix420, ZhymabekRoman
// ==/UserScript==

(function() {
  function mediumRedirecter() {
    if (
      !window.location.hostname.includes('freedium.cfd') &&
      window.location.hostname.includes('medium.com') &&
      !window.location.href.endsWith('#bypass') &&
      !window.location.href.includes("/edit?source=")
    ) {
      window.location.href = 'https://freedium.cfd/' + window.location.href;
    }
  }

  mediumRedirecter();
})();

@ZhymabekRoman
Copy link

Thanks for your effort.

The original script works great for me. However, your solution has one small problem: it can't work on domains other than medium.com. Here is a small list of third-party domains:

  • uxplanet.org
  • osintteam.blog
  • ahmedelfakharany.com
  • drlee.io
  • generativeai.pub
  • towardsdev.com
  • infosecwriteups.com
  • thetaoist.online
  • devopsquare.com
  • bettermarketing.pub
  • itnext.io
  • betterprogramming.pub
  • curiouse.co
  • betterhumans.pub
  • uxdesign.cc
  • thebolditalic.com
  • codeburst.io
  • writingcooperative.com
  • entrepreneurshandbook.co
  • storiusmag.com
  • javascript.plainenglish.io
  • code.likeagirl.io
  • medium.datadriveninvestor.com
  • blog.det.life
  • python.plainenglish.io
  • blog.stackademic.com
  • ai.gopubby.com
  • blog.devops.dev
  • levelup.gitconnected.com
  • ai.plainenglish.io

And so on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment