JavaScriptで「rel=”noopener”」をつける方法
2019年8月現在、Androidでブラウザにchromeを使用していると、「target="_blank"」が付いていて「rel="noopener"」がついていないリンクに飛んだとき、リンクが開かないという挙動があるそうですね。
Lighthouseのスコア向上を狙っていて調べ物をしていた際にたまたま見かけた問題でしたが、私もちょうど「セキュリティの観点から対応せねば!」と思っていたところ。
商品リンクを綺麗に表示してくれるプラグイン「Rinker」のリンクに、「rel="noopener"」を付けたかったんです。
「target="_blank"」を外すなり、外部リンクプラグインを使うなりすれば簡単に対応はできるのですが……
外部リンクは別タブで開きたい!
出来ればプラグインはあんまり入れたくない!
そんなわけで、JavaScriptを使ってRinkerのリンクに「rel="noopener"」を付けてみましたのでコードのメモを残します。
追記:2020年10月現在、amp化準備のため、当ブログでは本記事にアップしていることは実践しておりません。備忘録として残しています。
「rel="noopener"」とは
別タブで開いてくれる「target="_blank"」、大変身近なんですが、実はセキュリティ面で問題が。
詳細は以下のブログで大変詳しく説明してくださっています。
ざっくり言うと、別タブで開かれたリンク先のページから元ページを操作することが出来てしまう……なんてことが出来ちゃうんですね。
その他パフォーマンスが低下してしまったり、良いことが全然ありません。
でも、別タグは開きたい。
そんなときに助けてくれるのが「rel="noopener"」です。
これをつけることでリンク先のページで元ページの操作を禁止してくれる、ヒーローなんです。
現在のWordPressでは、外部リンクに「target="_blank"」をつけると「rel="noopener"」が自動的に入るようになっています。
なので問題なさそうに見えるのですが……
ショートコードは自動挿入の対象外!
↑こういったRinkerなどのショートコードで呼び出されるリンクには、「rel="noopener"」がつかないんですよね。落とし穴。
こちらが今、セキュリティ強化によるバージョンアップの影響なのか、Androidのchromeでは開くことができない場合もあるそうです。
購入したい人も購入して欲しい人も、お互い損な状態になってしまいますね。。
そんなわけで、こういった「rel="noopener"」がつかない問題は、個別になんとかしないといけないのです。
JavaScriptでRinkerのリンクに「rel="noopener"」追加
私はプラグインを入れたくなかったので、JavaScriptで対応することに。
Luxeritasの場合、記述箇所は以下。
- Luxeritas > 子テーマの編集 > JavaScript
当ブログでJavaScriptに書いたのは以下のコードです。
let rinkerArray = document.querySelectorAll(".yyi-rinker-contents a[rel='nofollow']");
rinkerArray.forEach((link)=>{
link.rel += ' noopener'
})
Rinkerのリンク全てに「noopener」をつけたいのですが、「created by Rinker」の部分だけもともと「rel="nofollow noopener"」が入っていました。(テーマによるのかもしれない?)
そのほかのリンクは広告なので「rel="nofollow"」がついていましたが、「noopener」がありません。
全てのリンクに「noopener」をつけようとすると「created by Rinker」の部分に「noopener」が二重で入ってしまうため、「(“.yyi-rinker-contents a[rel=’nofollow’]")」と、「rel="nofollow"」だけが入っているリンクを指定して抜き出しました。
そして、「+= ' noopener’」で「noopener」を追加してみました。
追記:2020年10月現在、amp化準備のため、当ブログでは本記事にアップしていることは実践しておりません。備忘録として残しています。
Rinkerのリンク全てに「noopener」を付けたい場合
上記「created by Rinker」のリンクにだけ「noopener」が付いている件、もしかしたらテーマによるのかもしれません。(私はLuxeritas 3.6.11使用)
もともと全てに「noopener」がない場合は、以下のコードを書くと良いと思います。
let rinkerArray = document.querySelectorAll(".yyi-rinker-contents a");
rinkerArray.forEach((link)=>{
link.rel += ' noopener'
})
これで「.yyi-rinker-contents」内のaタグ全てに適用されるはずです。
注意点
JavaScriptでの追加なので、たとえばLighthouse等のチェックではスコアに反映されません。
該当箇所に「noopenerを追加しなさい!」と怒られてしまいます。。
これは正しくできていないわけじゃなくて、JavaScriptで書いているからです。
JavaScriptはページを全部表示した後に、もともと書かれているものに対して「やっぱりこれ、こっちにして!」とお願いするもの。
そしてお願い前の状態をLighthouseがチェックしてしまい、正しく反映されませんでした。。
ただし、実際のページにはちゃんと「noopener」が追加されているので、その機能は果たしてくれます。
JavaScript以外にも選択肢はあり
「WP External Links」等、外部リンクに一括で「noopener」を追加できるようなプラグインもあります。
プラグインを入れるのが嫌でなければ、それが一番楽チンかも。
私ももともとは入れていたのですが、使用しているテーマLuxeritasと機能が大きく被っているので削除しました。
プラグインが多くなると大変なことが多いので(サイトが重くなったり、エラーが出た時の原因探るのが難しかったり)、あんまりプラグインは増やしたくなくて、今回JavaScriptで対応してみました。
今後ますます様々なところでセキュリティが強化されそうですね。
サイトの対策もしっかりしなければです!
ディスカッション
コメント一覧
まだ、コメントがありません