WordPress: скрыть внешние ссылки на JavaScript без сторонних плагинов

MY  

Очень простой код для скрытия внешних ссылок на нативном JavaScript. Плагин перебирает в DOM все ссылки и по заданным параметрам подставляет к ним префикс, а также дополнительно скрывает искомую ссылку на base64.

Подпишись на Telegram

Ранее использовал плагин для CMS WordPress под названием Hide External Links. У него такой же принцип работы, И он устанавливается в админку CMS. Плагин не поддерживает PHP 8.0 и выдает кучу ошибок.

Описание плагина

Плагин не имеет административного интерфейса и состоит лишь из маленького JavaScript кода и php файла, на который перенаправляются все ссылки.

Краткое описание и пример работы: https://code.itikhonov.art/index.php?page=exlinks

  • полностью нативный JavaScript;
  • отдельная php-страница для переадресации пользователя;
  • белый список доменов в виде массива;
  • обработка страницы полностью на стороне клиента;
  • ничего не перезаписывается и не изменяется в структуре сайта;
  • шифрование ссылок для визуального эффекта.

Установка плагина

В папку с темой WordPress (wp-content/themes/your_theme_name) загрузить javascript файл из архива и по желанию зарегистрировать его в файле functions.php также в своей теме. По крайней мере так более правильно.

Но для текущего решения это не имеет никакого смысла т.к. скрипт очень маленький. Проще внести его в файл инициализации (я так его называю), где хранятся небольшие скрипты. Например, у меня это реализовано вот так:

https://itikhonov.art/wp-content/themes/artlife/js/clean-blog.js

2. В корень сайта добавить файл go.php

3. Внести изменения в .htaccess (см. ниже)

JavaScript

    // #######################
    // СКРЫТИЕ ВНЕШНИХ ССЫЛОК
    // #######################

    // получаем все ссылки на странице
    var links = document.querySelectorAll('a[href]'),

    // Получаем домен текущего сайта
    host = window.location.origin;

    // список исключений (слеш в конце обязательно)
    var exclude = [

        'https://exclude.name/'

    ]
        
    // проверяем каждую ссылку в цикле
    for(let i = 0; i < links.length; i++){

        // проверяем, что текущая ссылка не является доменом сайта          
        if(links[i].origin !== window.location.origin){

            // и вешаем на нее открытие в новой вкладке
            links[i].setAttribute('target', '_blank');

            // проверяем ссылку на наличие исключений
            if(!exclude.includes(links[i].href)){           

                // проверяем ее дополнительно на наличие rel="follow"
                if(links[i].getAttribute('rel') != 'follow'){

                    // декодируем в base64 и подставляем префикс /go/
                    links[i].href = '/go/' + btoa(links[i].href);

                    // или без .htaccess редиректов
                    // links[i].href = '/go.php?go=' + btoa(links[i].href);


                }
            }
            
        }
        
    }

Теперь все внешние ссылки, которые не содержат атрибут rel=”follow” будут кодироваться в виде:

mysite.name/go/very_long_base64_encode_url 

Если нужно оставить внешнюю ссылку без кодирования, нужно записывать ее в виде:

<a hre="https://someurl.name" rel="follow">Link text</a>

Редирект через .htaccess

В корне сайта найти файл .htaccess и в самое начало добавить следующий код:

RewriteEngine On
RewriteRule ^go$ ^go/1$ [L]
RewriteRule ^go/(.+)(/?)$ go.php?go=$1 [L]
RewriteRule ^go(/+) go.php [L]

PHP обработчик

Код слегка громоздкий, поэтому покажу скриншот и прикреплю все исходники для скачивания

Ссылку мы передаем на внешнюю страницу в качестве GET параметра /go/sometext. В .htaccess делаем нашу ссылку визуально красивее и избавляемся от старомодных /index.php?go=sometext

Поэтому делаем две проверки: на наличие GET вообще и если все ок, то проверяем нужный нам GO.

Далее выводим визуал на HTML и завершаем редиректом на искомый сайт.

Баги и фиксы на будущее

Jetpack предоставляет возможность подгружать изображения на наш сайт через их сервера (своеобразный CDN и полезная штука). Данный плагин воспринимает такие ссылки, как внешние.

Это не критично, если вы не используете кликабельные картинки (или их плавное увеличение в модальном окне).

В будущем переделаю проверку ссылок из массивов и дополню, как минимум, методом indexOf()

Быстрый фикс: каждый такой адрес добавить в белый список в массив exclude

Файлы для скачивания