<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>JavaScript アーカイブ - Sheltie Garage Tech</title>
	<atom:link href="https://sheltie-garage.xyz/tech/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>https://sheltie-garage.xyz/tech/category/javascript/</link>
	<description>テクノロジー関連の話題をまとめたブログです</description>
	<lastBuildDate>Sat, 04 Oct 2025 09:33:25 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Next.jsでMetatag(OGPタグ)を返却する</title>
		<link>https://sheltie-garage.xyz/tech/2025/10/next-js%e3%81%a7metatagogp%e3%82%bf%e3%82%b0%e3%82%92%e8%bf%94%e5%8d%b4%e3%81%99%e3%82%8b/</link>
					<comments>https://sheltie-garage.xyz/tech/2025/10/next-js%e3%81%a7metatagogp%e3%82%bf%e3%82%b0%e3%82%92%e8%bf%94%e5%8d%b4%e3%81%99%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[monodon]]></dc:creator>
		<pubDate>Sat, 04 Oct 2025 09:31:04 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[React]]></category>
		<guid isPermaLink="false">https://sheltie-garage.xyz/tech/?p=1273</guid>

					<description><![CDATA[<p>React + Next.jsで作成したアプリ(フロントエンド)からOGPタグを返却したかったので調査したときのメモです OGPタグはなぜ必要？ XServerさんの説明はこちらhttps://www.xserver.n [&#8230;]</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2025/10/next-js%e3%81%a7metatagogp%e3%82%bf%e3%82%b0%e3%82%92%e8%bf%94%e5%8d%b4%e3%81%99%e3%82%8b/">Next.jsでMetatag(OGPタグ)を返却する</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[
<p>React + Next.jsで作成したアプリ(フロントエンド)からOGPタグを返却したかったので調査したときのメモです</p>



<h2 class="wp-block-heading">OGPタグはなぜ必要？</h2>



<p>XServerさんの説明はこちら<br><a href="https://www.xserver.ne.jp/bizhp/open-graph-protocol/" target="_blank" rel="noreferrer noopener">https://www.xserver.ne.jp/bizhp/open-graph-protocol/</a></p>



<p>ざっくりな内容として「SNSなどにリンクをシェアしたときに、タイトルや画像を表示するための仕組み」です<br>今回、趣味開発しているWebアプリに「SNSで投稿内容をシェアするためのURLを発行する」機能を追加するにあたり、X(Twitter)などに画像やタイトルを表示させる必要があったため、OGPタグを追加することにしました。<br>(ちなみに、自分が作成しているサイトはライダー向けツーリングスポット共有サイトで、マップ上にスポットを投稿できるようなWebサイトです)</p>



<p>↓こんな感じで、Xポスト内に投稿した内容が画像付きで表示されるようになります</p>



<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ヤギ！柵まで近づいてきてくれて可愛かった！<br> <a href="https://t.co/YMV9Hki6hV">https://t.co/YMV9Hki6hV</a> <a href="https://twitter.com/hashtag/ProjectRIDE?src=hash&amp;ref_src=twsrc%5Etfw">#ProjectRIDE</a> <a href="https://twitter.com/hashtag/%E3%83%84%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#ツーリング</a></p>&mdash; ProjectRIDE (@ProjectRID46883) <a href="https://twitter.com/ProjectRID46883/status/1973176508316524786?ref_src=twsrc%5Etfw">October 1, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



<h2 class="wp-block-heading">Next.jsでOGPタグを返却する仕組み</h2>



<p>Next.jsで開発するアプリでOGPタグを返却する場合、以下の2通りの方法が利用できます</p>



<ul class="wp-block-list">
<li>metadataオブジェクトを定義し、固定値を返却</li>



<li>generateMetaData関数を定義し、動的な値を返却</li>
</ul>



<h2 class="wp-block-heading">metadataオブジェクトを使用する場合</h2>



<p>固定ページなど、動的に情報を取得する必要がない場合metadataオブジェクトをlayout.jsやpage.jsに定義してメタデータ(OGPタグなど)を返却することができます<br><a href="https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadata-fields">https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadata-</a><a href="https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadata-fields" target="_blank" rel="noreferrer noopener">fields</a></p>



<p>動的な取得が必要なければ、こちらを利用するのが簡単そうですね!</p>



<h2 class="wp-block-heading">generateMetada関数を使用する場合</h2>



<p>例えば、ユーザーの投稿内容を表示するなど、内容を動的に取得する必要がある場合は「generateMetadata」ファンクションを使用する必要があります<br>https://nextjs.org/docs/app/api-reference/functions/generate-metadata</p>



<p>自分のサイトでは以下の方法で実装しています。実装先はapp/page.tsxになります</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-ts" data-lang="TypeScript"><code>type Props = {
  params: Promise&lt;{ id: string }&gt;
  searchParams: Promise&lt;{ [key: string]: string | string[] | undefined }&gt;
}

// SNSシェアリンク用のOGP生成処理
// https://www.project-ride.com/content_id=1 でアクセスされたときに実行される
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function generateMetadata({ params, searchParams }: Props, parent: ResolvingMetadata): Promise&lt;Metadata&gt; {
  
  const resolvedSearchParams = await searchParams
  const contentId = resolvedSearchParams.content_id
  const wwwBaseUrl = process.env.NEXT_PUBLIC_WWW_BASE_URL ?? &quot;&quot;
  const defaultImageUrl = `${process.env.NEXT_PUBLIC_IMAGE_BASE_URL ?? &quot;&quot;}${process.env.NEXT_PUBLIC_NO_IMAGE ?? &quot;&quot;}`  

  // もし content_id が URL にあれば...
  if (typeof contentId === &#39;string&#39;) {
    const content = await getContent(contentId);

    if (content) {
      const imageUrl = content.image_url
        ? (process.env.NEXT_PUBLIC_IMAGE_BASE_URL ?? &quot;&quot;) + content.image_url
        : defaultImageUrl;

      const title = content.message.replace(/&lt;br\s*\/?&gt;/gi, &#39;&#39;).substring(0, 30) + &#39;...&#39;;
      const description = content.message;

      return {
        title: title, // タイトル用にメッセージを短縮
        description: description,
        openGraph: {
          title: title,
          description: description,
          url: `${wwwBaseUrl}?content_id=${contentId}`,
          images: [{ url: imageUrl }],
        },
        twitter: {
          card: &#39;summary_large_image&#39;,
          title: title,
          description: description,
          images: [imageUrl],
        }
      }
    }
  }

  // 有効なコンテンツが見つからない場合、デフォルト内容を返却
  return {
    title: &#39;RIDE-Mono&#39;,
    description: &#39;バイク乗りのためのおすすめスポット共有サイト&#39;,
    openGraph: {
      title: &#39;RIDE-Mono&#39;,
      description: &#39;バイク乗りのためのおすすめスポット共有サイト&#39;,
      url: wwwBaseUrl,
      images: [{ url: &quot;&quot; }], // デフォルト画像
    }
  }
}</code></pre></div>



<p>スクリプト内のgetContent関数でユーザー投稿内容を取得し、メタデータを設定しています</p>



<p class="has-black-color has-text-color has-link-color wp-elements-c63e69e26ea30bb3dfa079b2bff16dd3">注意点としてgenerateMetadata関数は<strong>サーバーコンポーネント</strong>で実行する必要があります<br>自分が最初作成したとき、クライアントコンポーネントにてページを作成していたため、generateMetadata関数を利用するために、既存のページ内容を別途クライアントコンポーネントのファイルに別出しして対応を行いました</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>export default function Home() {
  return (&lt;TopPage /&gt;);
}</code></pre></div>



<p>もともと記載していた内容をTopPageコンポーネントに分離しています<br>TopPageコンポーネントでは、&#8217;use client&#8217;を利用し、クライアントコンポーネントとして動作させています</p>



<h2 class="wp-block-heading">プレビューが出ない時がある</h2>



<p>生成したリンクをX(Twitter)に貼り付けたときにプレビューが表示されたり、されなかったりといった症状がでてデバッグに苦戦しました<br>実際には投稿後に正しくOGPの内容が表示されたので、投稿前のプレビューの精度は参考程度に考えていたほうが良いのかもしれません(逆に投稿したのに、想定したOGPの内容が表示されない場合は、何かを間違えている可能性が高い)</p>



<h2 class="wp-block-heading">以上です</h2>



<p>ということでNext.jsからMetadata(OGPタグ)を返却する方法でした<br>SPAだとどうやってMetadataを返却しているのか正直謎でしたが、調べてみるときちんと仕組みが備わっているんですね！</p>



<p>Metadataを生成することで、SNSシェア以外にもクローラー対応など、色々できることが増えそうです</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2025/10/next-js%e3%81%a7metatagogp%e3%82%bf%e3%82%b0%e3%82%92%e8%bf%94%e5%8d%b4%e3%81%99%e3%82%8b/">Next.jsでMetatag(OGPタグ)を返却する</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sheltie-garage.xyz/tech/2025/10/next-js%e3%81%a7metatagogp%e3%82%bf%e3%82%b0%e3%82%92%e8%bf%94%e5%8d%b4%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AxiosでHTTPステータスに応じた処理を実行する</title>
		<link>https://sheltie-garage.xyz/tech/2024/08/axios%e3%81%a7http%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%81%ab%e5%bf%9c%e3%81%98%e3%81%9f%e5%87%a6%e7%90%86%e3%82%92%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b/</link>
					<comments>https://sheltie-garage.xyz/tech/2024/08/axios%e3%81%a7http%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%81%ab%e5%bf%9c%e3%81%98%e3%81%9f%e5%87%a6%e7%90%86%e3%82%92%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[monodon]]></dc:creator>
		<pubDate>Wed, 14 Aug 2024 23:26:26 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://sheltie-garage.xyz/tech/?p=1090</guid>

					<description><![CDATA[<p>今作成しているWebアプリで、エラーが発生したときにHTTPステータスを利用してエラーを示すように作成しています。AxiosはデフォルトでHTTPステータスが200以外の場合、例外を出力して終了するようなので、インターセ [&#8230;]</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2024/08/axios%e3%81%a7http%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%81%ab%e5%bf%9c%e3%81%98%e3%81%9f%e5%87%a6%e7%90%86%e3%82%92%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b/">AxiosでHTTPステータスに応じた処理を実行する</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[
<p>今作成しているWebアプリで、エラーが発生したときにHTTPステータスを利用してエラーを示すように作成しています。<br>AxiosはデフォルトでHTTPステータスが200以外の場合、例外を出力して終了するようなので、インターセプターを利用して独自の処理を利用できるようにします。</p>



<h2 class="wp-block-heading">早速ですが、コードです</h2>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>    // Axiosインスタンスを作成
    const apiClient = axios.create({
      withCredentials: true, // クッキーを含める設定
    });

    // レスポンスインターセプターを設定
    apiClient.interceptors.response.use(
      (response) =&gt; {
        // 成功時の処理
        return response;
      },
      (error) =&gt; {
        if (error.response && error.response.status === 401) {
          // 401エラー時の独自の処理
          console.error(&#39;認証に失敗&#39;);
        }
        return Promise.reject(error);
      }
    );

    // APIを実行
    apiClient
      .post(registerURL, registerParam)
      .then((response) =&gt; {
        console.log(&#39;認証に成功&#39;);
      });</code></pre></div>



<p>apiClient.interceptors.response.useを利用してHTTPステータスに対応した独自の処理を作成できます。<br>上記の例では401ステータスが返却された場合の処理が定義されています。</p>



<p>今作成しているアプリでは、ログインの認証に失敗すると401エラーが返却されるので、その場合は「ログインID,パスワードが違います」といったようなエラーメッセージを設定するような処理を行っています。</p>



<h2 class="wp-block-heading">以上</h2>



<p>短いですが、AxiosでHTTPステータスに応じた処理を実行する方法を記載しました。<br>HTTPステータスは色々種類があるため、エラーの状況に応じて適切なHTTPステータスを返却するように処理を作り込んでいこうと思います。</p>


<div id="rinkerid1091" class="yyi-rinker-contents  yyi-rinker-postid-1091 yyi-rinker-img-m yyi-rinker-catid-19 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FRESTAPI%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/rakutenkobo-ebooks/cabinet/9299/2000000959299.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FRESTAPI%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">REST API Design Rulebook Designing Consistent RESTful Web Service Interfaces【電子書籍】[ Mark Masse ]</a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥906</span>
															<span class="price_at">(2026/04/07 20:50:42時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=RESTAPI&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FRESTAPI%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3DRESTAPI" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>


<div id="rinkerid1092" class="yyi-rinker-contents  yyi-rinker-postid-1092 yyi-rinker-img-m yyi-rinker-catid-19 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FHTTP%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/6258/9784798126258.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FHTTP%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">HTTPの教科書 強靱な技術力と柔軟な思考を味方にするWebプロトコ [ 上野宣 ]</a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥2,860</span>
															<span class="price_at">(2026/04/07 20:50:42時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=HTTP&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FHTTP%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3DHTTP" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2024/08/axios%e3%81%a7http%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%81%ab%e5%bf%9c%e3%81%98%e3%81%9f%e5%87%a6%e7%90%86%e3%82%92%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b/">AxiosでHTTPステータスに応じた処理を実行する</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sheltie-garage.xyz/tech/2024/08/axios%e3%81%a7http%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9%e3%81%ab%e5%bf%9c%e3%81%98%e3%81%9f%e5%87%a6%e7%90%86%e3%82%92%e5%ae%9f%e8%a1%8c%e3%81%99%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Chromeブラウザの拡張機能を作ってみる</title>
		<link>https://sheltie-garage.xyz/tech/2024/02/chrome%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/</link>
					<comments>https://sheltie-garage.xyz/tech/2024/02/chrome%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/#respond</comments>
		
		<dc:creator><![CDATA[monodon]]></dc:creator>
		<pubDate>Tue, 27 Feb 2024 01:31:41 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<guid isPermaLink="false">https://sheltie-garage.xyz/tech/?p=1001</guid>

					<description><![CDATA[<p>唐突に拡張機能を作ってみたくなったので、最低限の環境を作る方法をメモしておきます。参考にしたのはこちらの記事https://qiita.com/RyBB/items/32b2a7b879f21b3edefc 個人的にAm [&#8230;]</p>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2024/02/chrome%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/">Chromeブラウザの拡張機能を作ってみる</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></description>
										<content:encoded><![CDATA[
<p>唐突に拡張機能を作ってみたくなったので、最低限の環境を作る方法をメモしておきます。<br>参考にしたのはこちらの記事<br><a href="https://qiita.com/RyBB/items/32b2a7b879f21b3edefc" target="_blank" rel="noreferrer noopener">https://qiita.com/RyBB/items/32b2a7b879f21b3edefc</a></p>



<p>個人的にAmazon検索の隠しパラメータを手軽に利用できる拡張機能を作って公開してみました<br><a href="https://chromewebstore.google.com/detail/amazon%E8%A3%8F%E6%8A%80%E6%A4%9C%E7%B4%A2/gbgfbnmcnkhddoahjhehomlccblhbedi?hl=ja&amp;utm_source=ext_sidebar" target="_blank" rel="noreferrer noopener">https://chromewebstore.google.com/detail/amazon%E8%A3%8F%E6%8A%80%E6%A4%9C%E7%B4%A2/gbgfbnmcnkhddoahjhehomlccblhbedi?hl=ja&amp;utm_source=ext_sidebar</a></p>



<h2 class="wp-block-heading">Chrome拡張機能の概要</h2>



<p>Chromeには様々な拡張機能を追加できます。</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="551" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/スクリーンショット-2024-02-27-9.31.59-1024x551.png" alt="" class="wp-image-1002" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/スクリーンショット-2024-02-27-9.31.59-1024x551.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/スクリーンショット-2024-02-27-9.31.59-300x161.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/スクリーンショット-2024-02-27-9.31.59-768x413.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/スクリーンショット-2024-02-27-9.31.59-1536x826.png 1536w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/スクリーンショット-2024-02-27-9.31.59-2048x1101.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Chromeの拡張機能はJavaScriptで作成できるので、意外と気軽に作成出来ます。<br>今回は特定のURLを開くとポップアップが表示される拡張機能を作ります。</p>



<h2 class="wp-block-heading">Chrome拡張機能の最低限の構成</h2>



<p>Chrome拡張機能で最低限必要なのは以下の2ファイルになります</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="448" height="292" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_001.png" alt="" class="wp-image-1003" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_001.png 448w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_001-300x196.png 300w" sizes="auto, (max-width: 448px) 100vw, 448px" /></figure>



<p>それぞれのファイルの中身は以下のとおりです。</p>



<p>manifest.jsonの中身</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>{
    &quot;name&quot;: &quot;MinimalProject&quot;,
    &quot;version&quot;: &quot;1.0.0&quot;,
    &quot;manifest_version&quot;: 3,
    &quot;description&quot;: &quot;ダイアログを表示します&quot;,
    &quot;permissions&quot;: [],
    &quot;content_scripts&quot;: [{
      &quot;matches&quot;: [&quot;https://www.google.co.jp/*&quot;],
      &quot;js&quot;: [
        &quot;content.js&quot;
      ]
    }]
}</code></pre></div>



<p>content.jsの中身</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>window.alert(&#39;google.co.jpを開きました&#39;);</code></pre></div>



<p>以上です。これだけで拡張機能として動作します。</p>



<h2 class="wp-block-heading">Chromeに開発中の拡張機能をインストールする</h2>



<p>開発中の拡張機能をChromeにインストールします。<br>まずは拡張機能の管理画面を開きます。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="775" height="1024" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_002-775x1024.png" alt="" class="wp-image-1004" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_002-775x1024.png 775w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_002-227x300.png 227w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_002-768x1015.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_002.png 884w" sizes="auto, (max-width: 775px) 100vw, 775px" /></figure>



<p>右上にあるデベロッパーモードをONにします</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="448" height="180" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_003.png" alt="" class="wp-image-1005" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_003.png 448w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_003-300x121.png 300w" sizes="auto, (max-width: 448px) 100vw, 448px" /></figure>



<p>「パッケージ化されていない拡張機能を読み込む」をクリックします</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="501" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_004-1024x501.png" alt="" class="wp-image-1006" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_004-1024x501.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_004-300x147.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_004-768x376.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_004.png 1296w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>ディレクトリの選択画面が表示されるので、manifest.jsonとcontent.jsが入っているディレクトリを選択します</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="610" height="334" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240277_005.png" alt="" class="wp-image-1007" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240277_005.png 610w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240277_005-300x164.png 300w" sizes="auto, (max-width: 610px) 100vw, 610px" /></figure>



<p>拡張機能が追加されたことを確認します</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="596" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006-1024x596.png" alt="" class="wp-image-1008" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006-1024x596.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006-300x175.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006-768x447.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006-1536x894.png 1536w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006-1200x700.png 1200w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_006.png 1690w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">動作確認を行う</h2>



<p>今回作成した拡張機能は「https://www.google.co.jp」にアクセスしたときにポップアップ(アラート)を表示する設定になっています。<br>拡張機能を有効化した状態でgoogle.co.jpにアクセスしてください。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="826" height="448" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_007.png" alt="" class="wp-image-1009" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_007.png 826w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_007-300x163.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_007-768x417.png 768w" sizes="auto, (max-width: 826px) 100vw, 826px" /></figure>



<p>ポップアップが表示されました</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="265" src="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_008-1024x265.png" alt="" class="wp-image-1010" srcset="https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_008-1024x265.png 1024w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_008-300x78.png 300w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_008-768x199.png 768w, https://sheltie-garage.xyz/tech/wp-content/uploads/2024/02/20240227_008.png 1520w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">以上です</h2>



<p>以上で最低限のChrome拡張機能の作成と動作確認まで紹介しました。<br>意外と手軽に作成できることがおわかりいただけたかと思います。<br>今回は特定のURLにアクセスしたときに動作するタイプの拡張機能となりますが、他にもいろいろなタイプの拡張機能が作成出来ます。<br>JavaScriptの知識があれば開発することができるので、ぜひ挑戦してみてください。</p>


<div id="rinkerid1011" class="yyi-rinker-contents  yyi-rinker-postid-1011 yyi-rinker-img-m yyi-rinker-catid-19 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FChrome%2B%25E6%258B%25A1%25E5%25BC%25B5%25E6%25A9%259F%25E8%2583%25BD%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/rakutenkobo-ebooks/cabinet/1138/2000003451138.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FChrome%2B%25E6%258B%25A1%25E5%25BC%25B5%25E6%25A9%259F%25E8%2583%25BD%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">Chrome・Chromebook定番「拡張機能」セレクションズ【電子書籍】[ 武井 一巳 ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							<span title="" class="price">¥660</span>
															<span class="price_at">(2026/04/07 20:50:42時点&nbsp;楽天市場調べ-</span><span title="このサイトで掲載されている情報は当サイトの作成者により運営されています。価格、販売可能情報は、変更される場合があります。購入時に楽天市場店舗（www.rakuten.co.jp）に表示されている価格がその商品の販売に適用されます。">詳細)</span>
																	</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=Chrome+%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2FChrome%2B%25E6%258B%25A1%25E5%25BC%25B5%25E6%25A9%259F%25E8%2583%25BD%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3DChrome%2B%25E6%258B%25A1%25E5%25BC%25B5%25E6%25A9%259F%25E8%2583%25BD" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>


<div id="rinkerid1012" class="yyi-rinker-contents  yyi-rinker-postid-1012 yyi-rinker-img-m yyi-rinker-catid-19 ">
	<div class="yyi-rinker-box">
		<div class="yyi-rinker-image">
							<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fjavascript%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow"><img decoding="async" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/2880/9784297132880_1_2.jpg?_ex=128x128" width="128" height="128" class="yyi-rinker-main-img" style="border: none;" loading="lazy"></a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</div>
		<div class="yyi-rinker-info">
			<div class="yyi-rinker-title">
									<a href="https://af.moshimo.com/af/c/click?a_id=3394378&#038;p_id=54&#038;pc_id=54&#038;pl_id=616&#038;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fjavascript%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow">改訂3版JavaScript本格入門 [ 山田 祥寛 ]</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">							</div>
			<div class="yyi-rinker-detail">
							<div class="credit-box">created by&nbsp;<a href="https://oyakosodate.com/rinker/" rel="nofollow noopener" target="_blank" >Rinker</a></div>
										<div class="price-box">
							</div>
						</div>
						<ul class="yyi-rinker-links">
																                    <li class="amazonlink">
						<a href="https://www.amazon.co.jp/gp/search?ie=UTF8&amp;keywords=javascript&amp;tag=monodon-22&amp;index=blended&amp;linkCode=ure&amp;creative=6339" rel="nofollow" class="yyi-rinker-link">Amazon</a>					</li>
													<li class="rakutenlink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616&amp;url=https%3A%2F%2Fsearch.rakuten.co.jp%2Fsearch%2Fmall%2Fjavascript%2F%3Ff%3D1%26grp%3Dproduct" rel="nofollow" class="yyi-rinker-link">楽天市場</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3394378&amp;p_id=54&amp;pc_id=54&amp;pl_id=616" width="1" height="1" style="border:none;">					</li>
													<li class="yahoolink">
						<a href="https://af.moshimo.com/af/c/click?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502&amp;url=https%3A%2F%2Fshopping.yahoo.co.jp%2Fsearch%3Fp%3Djavascript" rel="nofollow" class="yyi-rinker-link">Yahooショッピング</a><img loading="lazy" decoding="async" src="https://i.moshimo.com/af/i/impression?a_id=3442618&amp;p_id=1225&amp;pc_id=1925&amp;pl_id=18502" width="1" height="1" style="border:none;">					</li>
				                											</ul>
					</div>
	</div>
</div>
<p>投稿 <a href="https://sheltie-garage.xyz/tech/2024/02/chrome%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/">Chromeブラウザの拡張機能を作ってみる</a> は <a href="https://sheltie-garage.xyz/tech">Sheltie Garage Tech</a> に最初に表示されました。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://sheltie-garage.xyz/tech/2024/02/chrome%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%ae%e6%8b%a1%e5%bc%b5%e6%a9%9f%e8%83%bd%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%82%8b/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
