Size
3.7 KB
Version
1.1.1
Created
Jan 17, 2026
Updated
18 days ago
1// ==UserScript==
2// @name AniList to nzbs.moe Link
3// @description Adds a nzbs.moe search link to AniList anime pages
4// @version 1.1.1
5// @match https://*.anilist.co/*
6// @icon https://anilist.co/img/icons/favicon-32x32.png
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 function init() {
12 // Wait for the page to load and check if we're on an anime page
13 if (!window.location.pathname.includes('/anime/')) {
14 console.log('Not an anime page, skipping');
15 return;
16 }
17
18 // Use MutationObserver to wait for the external links section to load
19 const observer = new MutationObserver(debounce(() => {
20 addNzbsMoeLink();
21 }, 500));
22
23 observer.observe(document.body, {
24 childList: true,
25 subtree: true
26 });
27
28 // Try to add the link immediately in case the page is already loaded
29 addNzbsMoeLink();
30 }
31
32 function debounce(func, wait) {
33 let timeout;
34 return function executedFunction(...args) {
35 const later = () => {
36 clearTimeout(timeout);
37 func(...args);
38 };
39 clearTimeout(timeout);
40 timeout = setTimeout(later, wait);
41 };
42 }
43
44 function addNzbsMoeLink() {
45 // Check if we already added the link
46 if (document.querySelector('.external-link[href*="nzbs.moe"]')) {
47 console.log('nzbs.moe link already exists');
48 return;
49 }
50
51 // Find the external links section
52 const externalLinksWrap = document.querySelector('.external-links-wrap');
53 if (!externalLinksWrap) {
54 console.log('External links section not found yet');
55 return;
56 }
57
58 // Extract the AniList ID from the URL
59 // URL format: https://anilist.co/anime/106967/Miru-Tights/
60 const urlMatch = window.location.pathname.match(/\/anime\/(\d+)/);
61 if (!urlMatch) {
62 console.log('Could not extract AniList ID from URL');
63 return;
64 }
65
66 const anilistId = urlMatch[1];
67 console.log('Found AniList ID:', anilistId);
68
69 // Create the nzbs.moe series URL using the AniList ID
70 const seriesUrl = `https://nzbs.moe/series/al/${anilistId}`;
71
72 // Create the link element matching the existing style
73 const nzbsLink = document.createElement('a');
74 nzbsLink.setAttribute('data-v-c1b7ee7c', '');
75 nzbsLink.href = seriesUrl;
76 nzbsLink.className = 'external-link';
77 nzbsLink.target = '_blank';
78 nzbsLink.rel = 'noopener noreferrer';
79
80 // Create the icon wrapper
81 const iconWrap = document.createElement('div');
82 iconWrap.setAttribute('data-v-c1b7ee7c', '');
83 iconWrap.className = 'icon-wrap';
84
85 // Create the icon image
86 const icon = document.createElement('img');
87 icon.setAttribute('data-v-c1b7ee7c', '');
88 icon.className = 'icon';
89 icon.src = 'https://nzbs.moe/favicon.ico';
90 icon.alt = 'nzbs.moe';
91
92 iconWrap.appendChild(icon);
93
94 // Create the name span
95 const nameSpan = document.createElement('span');
96 nameSpan.setAttribute('data-v-c1b7ee7c', '');
97 nameSpan.className = 'name';
98 nameSpan.textContent = 'nzbs.moe';
99
100 // Assemble the link
101 nzbsLink.appendChild(iconWrap);
102 nzbsLink.appendChild(nameSpan);
103
104 // Add the link to the external links section
105 externalLinksWrap.appendChild(nzbsLink);
106
107 console.log('Successfully added nzbs.moe link:', seriesUrl);
108 }
109
110 // Initialize when the page is ready
111 if (document.readyState === 'loading') {
112 document.addEventListener('DOMContentLoaded', init);
113 } else {
114 init();
115 }
116})();