プレスリリースやお知らせ、開発ブログ、会社の活動状況、Mattermost・aws・AI等の技術情報などを発信しています。

[小ネタ]サイト内のリンクは外部サイトなら別タブで開きたいし、遷移先が計測対象なら計測用パラメータつけたい

こんにちは sakasai です。

サイトからの離脱防止や場所によってはUX観点などの理由で、外部サイトに遷移するリンクを別タブで開く(target="_blank")ようにすることが多いと思います。

自前で実装したサイト(静的・動的関わらず)ならリンクに応じて要件通りの実装をすればいいのですが、WordPressでブログなど運用していると、記事内のリンクを別タブで開くようにし忘れたり、サイドバーなどでWordPressテーマのウィジェットなどを使っていると、別タブで開く設定がそもそもできなかったりする場合がたまにあります。

それでもやっぱり外部サイトへのリンクは別タブで開きたいんだよなぁ・・・ということでやってみましたので、当ブログ(WordPress)での実現方法を例にご紹介します。

追加で遷移先が自社サービスのLPなど流入を計測したいといった場合にGoogleAnalyticsのUTMパラメータを付与するといったことも同時に行っています。

注意点:

ページ内のにあるリンクを一律操作するため、場合によっては挙動がおかしくなったりする場合があるかもしれません。

以下紹介する方法を用いる場合は自己責任でお願いします。不具合等が発生した場合も保証はいたしかねますのでご了承ください。

JavaScriptの実装

まず最初にページ内のリンクを操作するJavaScriptを用意します。

(function (location, document) {
    'use strict';

    const NON_BLANK_TARGET_URLS = [
        'https://www.d-make.co.jp/blog',
        'https://d-make.co.jp/blog',
        '/blog'
    ];

    const ADD_UTM_PARAM_URLS = [
        'https://www.d-make.co.jp',
        'https://d-make.co.jp',
        'https://chat.remocla.online',
        'https://www.skill-sheet.com',
        'https://topvoice.biz'
    ];

    function hasQueryString(hrefString) {
        const url = new URL(hrefString);
        return url.searchParams.toString() !== '';
    }

    function hasUtmParams(hrefString) {
        const url = new URL(hrefString);
        return url.searchParams.get('utm_source') !== null;
    }

    function getUtmContent() {
        const pathSegments = location.pathname.split('/');
        return pathSegments.length > 5 ? pathSegments.slice(0, 5).join('/') : location.pathname;
    }

    function getUtmParams(hasQueryStringFlag) {
        const utmParams = {
            utm_source: 'd-make.co.jp_blog',
            utm_medium: 'blog',
            utm_campaign: 'dmake_blog',
            utm_content: getUtmContent()
        }
        const utmQueryStrings = new URLSearchParams(utmParams).toString();
        return `${hasQueryStringFlag ? '&' : '?'}${utmQueryStrings}`;
    }

    function processAnchors() {
        document.querySelectorAll('a').forEach(function(anchorElement) {
            const hrefString = anchorElement.href;

            if (!hrefString || NON_BLANK_TARGET_URLS.some(url => hrefString.startsWith(url))) {
                return;
            }

            anchorElement.setAttribute('target', '_blank');
            anchorElement.setAttribute('rel', 'noreferrer noopener');
            
            if (ADD_UTM_PARAM_URLS.some(url => hrefString.startsWith(url)) && (!hasQueryString(hrefString) || !hasUtmParams(hrefString))) {
                anchorElement.setAttribute('href', `${hrefString}${getUtmParams(hasQueryString(hrefString))}`);
            }
        });
    }

    try {
        processAnchors();
    } catch (e) {
        console.error('custom_enqueue.js error', e);
    }
})(location, document);

簡単に解説します。

HTML内のaタグのhref属性が当ブログのURL以外の場合に別タブで開きたいので、以下を別タブで開かないURLとして定義しています。

    const NON_BLANK_TARGET_URLS = [
        'https://www.d-make.co.jp/blog',
        'https://d-make.co.jp/blog',
        '/blog'
    ];

UTMパラメータを付与して遷移したいURL(ブログ外の自社サイト、自社サービスLPのURLなど)を以下に定義しています。

    const ADD_UTM_PARAM_URLS = [
        'https://www.d-make.co.jp',
        'https://d-make.co.jp',
        'https://chat.remocla.online',
        'https://www.skill-sheet.com',
        'https://topvoice.biz'
    ];

getUtmParams関数内の以下でUTMパラメータの値を定義しています。(utm_contentにページURLパスの先頭を設定するようにしています)

        const utmParams = {
            utm_source: 'd-make.co.jp_blog',
            utm_medium: 'blog',
            utm_campaign: 'dmake_blog',
            utm_content: getUtmContent()
        }

全体処理としてはページ表示時にprocessAnchors関数が実行されて以下を行っています。

  1. ページ内のaタグを抽出
  2. aタグのhref属性の値が”別タブで開かないURL”でない場合、target属性(target="_blank")とrel属性(rel="noreferrer noopener")を付与
  3. aタグのhref属性の値が”UTMパラメータを付与するURL”の場合、href属性の値にUTMパラメータを付与
    • 元の値にUTMパラメータが付与されている場合はそのままの値を使用する

上記の処理が行われると該当のリンクが別タブで開くようになり、計測対象URLにUTMパラメータが付与された状態になります。

今回作ったJavaScriptをChatGPT(GPT-4)にレビューしてもらって仕上げました。冗長な箇所の削除とか最適な関数を使ったりとか修正してもらいました。ありがたい。

JavaScriptをWordPressに登録

WordPressに自分で実装したJavaScriptを登録する場合、プラグインを使うなどいくつかやり方があると思いますが、今回は色々検索してみたところ推奨らしい方法のWordPress関数を使うやり方をご紹介します。(このやり方の場合サーバーにJavaScriptをアップロードする必要があるので、手軽にやりたい人はプラグインなどを検討してください)

  1. 実装したJavaScriptファイルをWordPressサーバーにアップロードします。
    • アップロード場所:テーマのディレクトリ配下
      • wp-content/themes/{theme name} # バージョンやテーマによっては別の場所の可能性があります。
  2. WordPress管理画面でテーマファイルエディタを開き、テーマの functions.php を開きます
  3. functions.php に以下のコードを追加して保存(ファイルの更新)を行うと、アップロードしたJavaScriptが反映されます。
function custom_enqueue_script() {
	wp_enqueue_script(
		'custom_script',
		// get_template_directory_uri() . '/{アップロードしたJavaScriptファイル}',
		get_template_directory_uri() . '/custom_enqueue.js',
		array(), '0.0.1', true
	);
}
add_action('wp_enqueue_scripts', 'custom_enqueue_script');

例えば

当ブログにすでに上記反映されていますので以下で確認してみます。

すべて別タブで開く設定をせずにリンクを張っています。

実際の挙動とChromeデベロッパーツールなどでHTMLタグがどうなっているか見てみてください。

さいごに

JavaScriptのソースコードはGitHubにもアップしています。

https://github.com/msakasai/wodpress-js/blob/main/custom_enqueue.js

参考になれば幸いです。

  • B!

おすすめ記事リンク