iOSのSafariでSNSリンクが表示されない問題解決編

makotoのブログアイコン
マコトノトコノマ

safariのコンテンツブロッカーがブロックしてたー

昨日のブログでなんでやろーかーってなってた問題

PCのブラウザで見た時、Android端末で見た時は、シェアボタンが表示され、機能するのに

なぜか

iPhoneのSafariだけ

そもそも表示されない問題が発生していました

こんなとき
「そんなこともあるよねー、Safariの仕様だからしょうがないんじゃーん」
という人生か
これは、チャンス到来!やっほーーい
という人生か
二つの分かれ道が
見えてしまうのです

そして、僕がどちらを選ぶかと言えば、ご想像の通りなのです

「なんでこんなこと起こるんやろう」ということが、定期的に出現するのが
この世の設定なので、通常運転なのです。

そして!なんと
おんなじことを、世界中の人が(大袈裟)悩んでいることを知ったのです

例えばこんな感じ↓

Screenshot

みーーーーんな困っていた

そして試行錯誤の結果、原因がわかりました
それが、

safariのコンテンツブロッカーがブロックしてたー

なのです
どういうこと?

Appleはさまざまなクリック詐欺などの、脅威に対抗するため、非常にセキュリティを強固にし、かつ頻繁に内容をアップデートしているのです
だから、知らん間にいろんな設定項目が追加されているのです

↑これね
これはAppleの公式見解 https://support.apple.com/ja-jp/102524

なるほど
では、どうやってそれがわかったか
それが重要です(あくまで開発者目線)

うまくいっているとことを一つづつ追加して、何がうまくいっていないかを絞り込む

僕は、webやる前は、DTP(紙媒体のデザイン)オンリーの世界にいまして、当時ライブハウスを運営しながら、コマネズミのように印刷物を作っていたのですが
僕の数少ない師匠と呼ぶ、デザイナーの方が言っていた言葉

「かっこいい」は
「かっこ悪いことを」ひとつひとつ、削ぎ落としていくことでしか
だどりつけない

の応用編で

「うまくいく」は
「うまくいかない」をひとつひとつ、削ぎ落としていくことでしか
だどりつけない

というやりかたです

さぁやってみよう!ということで昨日の続き、スタートラインはここ

---
const { url } = Astro;
const { title } = Astro.props;

const pageUrl = encodeURIComponent(url.href);
const pageTitle = encodeURIComponent(title);
---

<div class="jz-share-buttons">
	<a
		href={`https://twitter.com/intent/tweet?url=${pageUrl}&text=${pageTitle}`}
		target="_blank"
		rel="noopener noreferrer"
		aria-label="Twitterでシェア"
		class="jz-share-button twitter"
	>
		<i class="lab la-twitter"></i> Twitter
	</a>
	<a
		href={`https://www.facebook.com/sharer/sharer.php?u=${pageUrl}`}
		target="_blank"
		rel="noopener noreferrer"
		aria-label="Facebookでシェア"
		class="jz-share-button facebook"
	>
		<i class="lab la-facebook-f"></i> Facebook
	</a>
	<a
		href={`https://social-plugins.line.me/lineit/share?url=${pageUrl}`}
		target="_blank"
		rel="noopener noreferrer"
		aria-label="LINEでシェア"
		class="jz-share-button line"
	>
		<i class="lab la-line"></i> LINE
	</a>
	<a
		href={`https://b.hatena.ne.jp/entry/panel/?url=${pageUrl}`}
		target="_blank"
		rel="noopener noreferrer"
		aria-label="はてなブックマークでシェア"
		class="jz-share-button hatena"
	>
		<i class="lab la-hatena"></i> はてブ
	</a>
</div>

これはシェアボタン部分のastroコンポーネントです

これが、iOSのsafariでのみ表示されない、ということが起こっていた
なので、まず第一の目標は「iOSのsafariでも、このシェアボタンが表示される」です

押して動作するかは、今考えない!
一回にひとつの解決に集中する

いろいろ同時に解決しようとしないのです、

よっしゃ

そこで

<a href={`https://twitter.com/intent/tweet?url=${pageUrl}&text=${pageTitle}`}
		target="_blank"
		rel="noopener noreferrer"
		aria-label="Twitterでシェア"
		class="jz-share-button twitter"
	>
		<i class="lab la-twitter"></i> Twitter
</a>

だけ取り出し(ほんまはxにせなあかんけど、後でやる)
これが表示されるたらOKにします

MacにiphoneをUSBで繋ぐとSafariでiphoneのSafariの開発者ツールを表示されることができるので
それをみながら….

そうすると、ん……
タグは出力されているのにグレーアウトしてるぞ、なんでグレーアウト?(有効になっていない)
でもスタイルでdisplay:noneとかvisibility:hiddenは当たっていないのに
なんでーーーーーーーーーーーーーーーーーーーーーーー
ってなっても、こんなことは慣れっこなので、動じない
表示されない可能性が一つ消えた ということで次

hrefの値を空にしたら…….

おおおおおおおお!表示された

ということは

URLが問題?

よし実験!
href=”https://twitter.comzzzzz/intent/tweet”

って存在しないURLにしてみたら……..

なんと表示されたのです!

ということとは
SNSシェアリンクがaタグ、かつリンク先が既知のSNSの場合、Safariのコンテンツブロッカーが発動して
表示させないようにしている

こういうことが起こっているとすると

buttonタグにして、jsでクリックイベント発生させリンク先に遷移させるようにすれば
aタグではないので、表示される はず! やってみよーー

---
const { url } = Astro;
const { title } = Astro.props;

const pageUrl = url.href;
const pageTitle = title;
---

<div
	id="shareButtons"
	class="jz-share-buttons"
	data-page-url={pageUrl}
	data-page-title={pageTitle}
>
	<button
		id="share-twitter"
		class="jz-share-button twitter"
		aria-label="Twitterでシェア"
	>
		<i class="lab la-twitter"></i> Twitter
	</button>
	<button
		id="share-facebook"
		class="jz-share-button facebook"
		aria-label="Facebookでシェア"
	>
		<i class="lab la-facebook-f"></i> Facebook
	</button>
	<button
		id="share-line"
		class="jz-share-button line"
		aria-label="LINEでシェア"
	>
		<i class="lab la-line"></i> LINE
	</button>
	<button
		id="share-hatena"
		class="jz-share-button hatena"
		aria-label="はてなブックマークでシェア"
	>
		<i class="lab la-hatena"></i> はてブ
	</button>
</div>
<script>
	document.addEventListener('DOMContentLoaded', () => {
		const container = document.getElementById('shareButtons');
		if (!container) return;

		const rawUrl = container.dataset.pageUrl || window.location.href;
		const rawTitle = container.dataset.pageTitle || document.title;

		// エンコードはこの段階で実行
		const encodedUrl = encodeURIComponent(rawUrl);
		const encodedTitle = encodeURIComponent(rawTitle);

		// SNS別リンク
		const links = {
			'share-twitter': https://twitter.com/intent/tweet?url=${encodedUrl}&text=${encodedTitle},
			'share-facebook': https://www.facebook.com/sharer/sharer.php?u=${encodedUrl},
			'share-line': https://social-plugins.line.me/lineit/share?url=${encodedUrl},
			'share-hatena': https://b.hatena.ne.jp/entry/panel/?url=${encodedUrl},
		};

		console.log('Share links:', links);

		// クリック時に window.open を即実行(iOS Safari対応)
		for (const [id, shareUrl] of Object.entries(links)) {
			const btn = document.getElementById(id);
			if (btn) {
				btn.onclick = () => {
					window.open(shareUrl, '_blank', 'noopener,noreferrer');
				};
			}
		}
	});
</script>

※astroをSSRモードで使用しているので、<script></script>がクライアントサイドで実行されます
よしどうや!
buttonタグやから問題ないやろ!だーーー
そしたら

表示されました!!

よし、次
次はクリックしてちゃんとシェアされるか
そしたら
twitterとfacebookはクリックしても、なーーーんも反応せん

よしよし、うまくいかないことは大歓迎

よく見ると、クリックした時にiOSのsafariのコンソールでエラーがでてるじゃないか
コンソールエラーはありがたい!エラーメッセージありがたい!

Content blocker prevented frame displaying https://www.jamzip.com/blog/makoto/2683?back_url=https://www.jamzip.com/ from loading a resource from https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.jamzip.com%2Fblog%2Fmakoto%2F2683%3Fback_url%3Dhttps%253A%252F%252Fwww.jamzip.com%252F&text=%E3%81%86%E3%81%BE%E3%81%8F%E3%81%84%E3%81%8B%E3%81%AA%E3%81%84%E3%81%93%E3%81%A8%E3%81%AF%E3%80%81%E9%9D%A2%E7%99%BD%E3%81%84

こんなメッセージ、Content blocker prevented frame displaying つまり
これは iOS Safari の「コンテンツブロッカー」機能が Twitter へのリクエストをブロックしている ことを示しています

またもコンテンツブロッカーか…..

buttonタグにして、jsで遷移というごまかしは通用せんかー
それぐらい、わるいことする人はやるわなーーー

さーどーする、どうしたらコンテンツブロッカーは許してくれる…

と、とりあえず寝ました
とりあえず寝るのめっちゃ大事
脳にたまったゴミは寝てる時しか排出されへんらしい

そして4時ごろはっと目が覚めて

「formで送信したら、正規の送信としてコンテンツブロッカーも判断してくれんじゃぁ?jsでずるっこしてないし」と、ぴかーーーんとなりまして

起きると同時にMacBookProの画面を開いて、だーーーーっと書いてみました

---
const { url } = Astro;
const { title } = Astro.props;

// クエリを削除した URL を生成
const cleanUrl = new URL(url.href);
cleanUrl.search = ''; // back_url などを含むクエリを削除
const pageUrl = cleanUrl.href;

const encodedUrl = encodeURIComponent(pageUrl);
const encodedTitle = encodeURIComponent(title);
---

<div class="jz-share-buttons">
	<!-- X (旧Twitter) -->
	<form
		action="https://twitter.com/intent/tweet"
		method="GET"
		target="_blank"
		rel="noopener noreferrer"
	>
		<input type="hidden" name="url" value={encodedUrl} />
		<input type="hidden" name="text" value={encodedTitle} />
		<button
			type="submit"
			class="jz-share-button twitter"
			aria-label="Xでシェア"
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				viewBox="0 0 1200 1227"
				width="16"
				height="16"
				fill="white"
				aria-hidden="true"
			>
				<path
					d="M958.2 0H1150L754.7 524.3L1226 1227H848.6L552.1 794.4L210.4 1227H18.3L438.5 667.2L0 0H388.5L654.2 389.5L958.2 0ZM893.2 1105.6H994.5L335.3 114.3H226.7L893.2 1105.6Z"
				></path>
			</svg>
		</button>
	</form>

	<!-- Facebook -->
	<form
		action="https://www.facebook.com/sharer/sharer.php"
		method="GET"
		target="_blank"
		rel="noopener noreferrer"
	>
		<input type="hidden" name="u" value={pageUrl} />
		<button
			type="submit"
			class="jz-share-button facebook"
			aria-label="Facebookでシェア"
		>
			<i class="lab la-facebook-f"></i> Facebook
		</button>
	</form>

	<!-- LINE -->
	<form
		action="https://social-plugins.line.me/lineit/share"
		method="GET"
		target="_blank"
		rel="noopener noreferrer"
	>
		<input type="hidden" name="url" value={encodedUrl} />
		<button
			type="submit"
			class="jz-share-button line"
			aria-label="LINEでシェア"
		>
			<i class="lab la-line"></i> LINE
		</button>
	</form>

	<!-- はてなブックマーク -->
	<form
		action="https://b.hatena.ne.jp/entry/panel/"
		method="GET"
		target="_blank"
		rel="noopener noreferrer"
	>
		<input type="hidden" name="url" value={encodedUrl} />
		<button
			type="submit"
			class="jz-share-button hatena"
			aria-label="はてなブックマークでシェア"
		>
			<i class="lab la-hatena"></i> はてブ
		</button>
	</form>
</div>

※しれっとtwitterをxにしている

そしたらなんと!

ちゃんとSNSリンクが表示され
ちゃんとシェアできるではありませんかーーー

うれしーーーーー

ひょっとして、「iOSのSafariでSNSシェアリンクが表示されない」を突破できたの、わたくしが世界初!かも?

ははは

役にたてばいいなー

うまくいかないことは楽しいですねー

SNSでシェアする

New Live

デリカテッセン Polaris [兵庫県神戸市] jamzIpLIVE in polaris出演者MARU(from沖縄)/jamzIp出店者詳細未定 詳細

BURNY [愛知県岡崎市] 四万十川Soul会議 愛知県岡崎会場開演15:00出演者タクロー/イギリスの犬/すずきのやすひと/佐中コーコー/jamzIp/他 詳細

デリカテッセン Polaris [兵庫県神戸市] jamzIpLIVE in polaris出演者モジオ31(fromシュメール=愛知)/jamzIp出店者詳細未定 詳細