このドキュメントは、Instagramの埋(う)め込(こ)みコードをNext.jsで使用(しよう)する方法について説(せつ)明(めい)しています。また、Reactコンポーネントをクライアントサイドでレンダリングする方法についても説明(せつめい)しています。最後(さいご)に、ESLintのエラーに対(たい)する解決策(かいけつさく)についても説明(せつめい)しています。
Nextjsで作(つく)っているブログにInstagramの埋(う)め込(こ)みをできるようにしたい
Instagramの埋(う)め込(こ)みをNext.jsのブログに追加(ついか)する方法(ほうほう)は、以下(いか)の手順(てじゅん)に従(したが)って行(おこな)うことができます。
react-instagram-embed
をインストールします。npm install react-instagram-embed
react-instagram-embed
をインポートします。import InstagramEmbed from 'react-instagram-embed'
InstagramEmbed
コンポーネントに渡(わた)します。<InstagramEmbed
url='<https://www.instagram.com/p/B9ZoTQ2jSSS/>'
/>
InstagramEmbed
コンポーネントにオプションを追加(ついか)することもできます。たとえば、maxWidth
プロパティを設定(してい)して、埋(う)め込(こ)みの最大(さいだい)幅(はば)を指定(してい)することができます。<InstagramEmbed
url='<https://www.instagram.com/p/B9ZoTQ2jSSS/>'
maxWidth={500}
/>
以上(いじょう)の手順で、Next.jsのブログにInstagramの埋め込みを追加することができます。
アクセストークンなしで自分(じぶん)以外(いがい)のInstagramの投稿(とうこう)をブログに埋(う)め込(こ)むことは可能(かのう)ですか?
残念(ざんねん)ながら、アクセストークンなしで自分(じぶん)以外(いがい)のInstagramの投稿(とうこう)をブログに埋(う)め込(こ)むことはできません。Instagramは、APIによるデータの取得(しゅとく)にアクセストークンを必要(ひつよう)としています。アクセストークンは、APIにアクセスするために必要(ひつよう)な認証情報(にんしょうじょうほう)の1つであり、Instagramがユーザーのプライバシーを保護(ほご)するために導入(どうにゅう)されています。
したがって、他(ほか)のユーザーのInstagramの投稿(とうこう)をブログに埋(う)め込(こ)むためには、そのユーザーが自分(じぶん)のアカウントでアクセストークンを生成(せいせい)して、そのアクセストークンを使用(しよう)してAPIからデータを取得(しゅとく)する必要(ひつよう)があります。
ただし、Instagramの公式(こうしき)ウェブサイトで提供(ていきょう)されている埋(う)め込(こ)み機能(きのう)を使用(しよう)すれば、アクセストークンなしでInstagramの投稿(とうこう)をブログに埋(う)め込(こ)むことができます。この場合(ばあい)、埋(う)め込(こ)み機能(きのう)を使用(しよう)するための埋(う)め込(こ)みコードが提供(ていきょう)されます。ただし、この方法(ほうほう)では、埋(う)め込(こ)み機能(きのう)に制限(せいげん)があることに注意(ちゅうい)してください。例(たと)えば、投稿()の詳細(しょうさい)な情報(じょうほう)を取得(しゅとく)したり、カスタマイズした埋め込みを作成(さくせい)したりすることはできません。
アクセストークンなしでInstagramの投稿(とうこう)をブログに埋(う)め込(こ)めることについて詳(くわ)しく知(し)りたいです。公式(こうしき)URLを教(おし)えて
Instagramの公式(こうしき)ウェブサイトで提供(ていきょう)されている埋(う)め込(こ)み機能(きのう)を使用(しよう)すると、アクセストークンなしでInstagramの投稿(とうこう)をブログに埋(う)め込(こ)むことができます。この方法では、埋(う)め込(こ)み機能(きのう)を使用(しよう)するための埋(う)め込(こ)みコードが提供(ていきょう)されます。ただし、この方法(ほうほう)では、埋(う)め込(こ)み機能(きのう)に制限(せいげん)があることに注意(ちゅうい)してください。例(たと)えば、投稿(とうこう)の詳細(しょうさい)な情報(じょうほう)を取得(しゅとく)したり、カスタマイズした埋(う)め込(こ)みを作成(さくせい)したりすることはできません。
以下(いか)は、Instagramの公式(こうしき)ウェブサイトで提供(ていきょう)されている埋(う)め込(こ)み機能(きのう)のURLです。
https://www.instagram.com/developer/embedding/
上記(じょうき)のURLにアクセスすると、埋(う)め込(こ)みコードを生成(せいせい)するための手順(しゅじゅん)が説明(せつめい)されています。埋(う)め込(こ)みコードを生成(せいせい)するためには、以下(いか)の手順(しゅじゅん)を実行(じっこう)する必要(ひつよう)があります。
以上(いじょう)の手順(しゅじゅん)で、アクセストークンなしでInstagramの投稿(とうこう)をブログに埋(う)め込(こ)むことができます。ただし、埋(う)め込(こ)み機能(きのう)には制限(せいげん)があるため、詳細(しょうさい)な情報(じょうほう)を取得(しゅとく)したり、カスタマイズした埋(う)め込(こ)みを作成(さくせい)したりするには、APIを使用(しよう)する必要(ひつよう)があります。
https://www.instagram.com/developer/embedding/を参照(さんしょう)して、埋(う)め込(こ)みコードを取得(しゅとく)しました。このコードをそのままNext.jsに貼(は)り付(つ)けるとエラーになります。修正(しゅうせい)する場所(ばしょ)を教(おし)えて下(くだ)さい
Instagramの埋込(うめこ)みコードをNext.jsに貼(は)り付(つ)けるとエラーが発生(はっせい)する可能性(かのうせい)があります。これは、Next.jsはクライアントサイドのJavaScriptをサポート(サポート)しているため、Reactコンポーネント内(ない)に直接(ちょくせつ)JavaScriptを埋(う)め込(こ)むことはできません。
代(か)わりに、Next.jsでは以下(いか)の手順(てじゅん)に従(したが)って、Instagramの埋(う)め込(こ)みコードを正常(せいじょう)に表示(ひょうじ)できるようにします。
以下(いか)は、この手順(てじゅん)を実行(じっこう)する方法(ほうほう)の例(れい)です。
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/BxxzD5pANZG/" data-instgrm-version="13">
<a href="https://www.instagram.com/p/BxxzD5pANZG/" target="_blank"></a>
</blockquote>
<script async src="//www.instagram.com/embed.js"></script>
import React, { useEffect } from "react";
const InstagramEmbed = () => {
useEffect(() => {
if (window.instgrm) {
window.instgrm.Embeds.process();
} else {
const script = document.createElement("script");
script.src = "//www.instagram.com/embed.js";
script.async = true;
script.defer = true;
document.body.appendChild(script);
}
}, []);
return (
<>
<blockquote
class="instagram-media"
data-instgrm-captioned
data-instgrm-permalink="https://www.instagram.com/p/BxxzD5pANZG/"
data-instgrm-version="13"
>
<a href="https://www.instagram.com/p/BxxzD5pANZG/" target="_blank"></a>
</blockquote>
</>
);
};
export default InstagramEmbed;
このコンポーネントは、useEffectフックを使用(しよう)して、Instagramの埋(う)め込(う)みJavaScriptライブラリがロードされるまで待機(たいき)します。ライブラリがロードされたら、コンポーネントは window.instgrm.Embeds.process()
を呼(よ)び出(だ)して、Instagramの埋(う)め込(こ)みコードをレンダリングします。
コンポーネントをクライアントサイドでレンダリングのやり方(かた)を教(おし)えて
Reactコンポーネントをクライアントサイドでレンダリングするには、次(つぎ)の手順(てじゅん)を実行(じっこう)する必要(ひつよう)があります。
next/dynamic
メソッドを使(つか)ってロード可能(かのう)な動的(どうてき)インポートとして指定(してい)します。import dynamic from 'next/dynamic'
const MyComponent = dynamic(() => import('../components/MyComponent'))
この方法(ほうほう)でコンポーネントを動的(どうてき)にインポートすると、必要(ひつよう)に応(おう)じてコンポーネントをクライアントサイドでロードし、レンダリングできます。
useEffect
フックを使()ってクライアントサイドでのレンダリングを処理する関数を実装します。import React, { useEffect, useState } from 'react'
import dynamic from 'next/dynamic'
const MyComponent = dynamic(() => import('../components/MyComponent'))
function MyPage() {
const [isClient, setIsClient] = useState(false)
useEffect(() => {
setIsClient(true)
}, [])
return (
<>
{isClient && <MyComponent />}
{!isClient && <div>Loading...</div>}
</>
)
}
export default MyPage
この方法(ほうほう)で、クライアントサイドでのレンダリングが実行(じっこう)され、コンポーネントがページに追加(ついか)されます。useEffect
フックを使(つか)って isClient
ステート変数(へんすう)を初期化(しょきか)することで、クライアントサイドでのレンダリングが行(おこ)われたかどうかを確認(かくにん)できます。初期(しょき)化(か)処理(しょり)を行(おこ)わないと、ページがサーバーサイドでレンダリングされたときに、クライアントサイドでコンポーネントが再度(さいど)レンダリングされてしまう可能性(かのうせい)があります。
以上(いじょう)の手順(てじゅん)に従(したが)うことで、Reactコンポーネントをクライアントサイドでレンダリングすることができます。
無事(ぶじ)開発(かいはつ)環境下(かんきょうか)でインスタグラムの埋(う)め込(こ)みを実装(じっそう)できました。ありがとう。
どういたしまして。問題(もんだい)が解決(かいけつ)できて良(よ)かったです。何(ほ)か他(ほか)に質問(しつもん)や問題(もんだい)があれば、いつでもお知(し)らせください。お力(ちから)になれるよう最善(さいぜん)を尽(つ)くします。
./components/notion-blocks/bookmark.tsx
36:35 Error: React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
38:3 Error: React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render. react-hooks/rules-of-hooks
上記(じょうき)のエラーメッセージに対(たい)して対応策(たいおうさく)を教(おし)えて下(くだ)さい
このエラーメッセージは、React Hooksが正(ただ)しい順序(じゅんじょ)で呼(よ)び出(だ)されていないことを示(しめ)しています。具体的(ぐたいてき)には、useState
とuseEffect
が条件(じょうけん)付(つ)きで呼(よ)び出(だ)されているため、問題(もんだい)が発生(はっせい)しています。
これらのHooksは常(つね)に同(おな)じ順序(じゅんじょ)で呼(よ)び出(だ)される必要(ひつよう)があります。つまり、useState
は常(つね)にコンポーネントの先頭(せんとう)で呼(よ)び出(だ)され、useEffect
は次(つぎ)に呼(よ)び出(だ)される必要(ひつよう)があります。
したがって、コンポーネント内(ない)でこれらのHooksを呼(よ)び出(だ)す前(まえ)に、条件(じょうけん)付(つ)きステートメントを移動(いどう)するか、別(べつ)の関数(かんすう)に分割(ぶんかつ)する必要(ひつよう)があります。
例(たと)えば、以下(いか)のように書(か)き換(か)えることができます。
import React, { useState, useEffect } from 'react';
const Bookmark = ({ block }: any) => {
const [showDescription, setShowDescription] = useState(false);
useEffect(() => {
if (block.properties.Description.title.length > 0) {
setShowDescription(true);
}
}, [block.properties.Description.title]);
return (
<div>
{showDescription && (
<div>{block.properties.Description.title[0].plain_text}</div>
)}
<div>
<a href={block.properties.Link.url} target="_blank" rel="noreferrer">
{block.properties.Title.title[0].plain_text}
</a>
</div>
</div>
);
};
export default Bookmark;
このコードでは、useState
とuseEffect
が常(つね)に同(おな)じ順序(じゅんじょ)で呼(よ)び出(だ)されるようになっています。
修正(しゅうせい)している途中(とちゅう)でエラーメッセージが出(で)ました。
Error: Objects are not valid as a React child (found: [object URL]). If you meant to render a collection of children, use an array instead.
対策(たいさく)を教(おし)えて下(くだ)さい
このエラーは、Reactが URL オブジェクトを子要素(こようそ)として直接(ちょくせつ)レンダリングしようとしていることを示(しめ)しています。Reactは、オブジェクトを文字列(もじれつ)としてレンダリングすることはできません。
このエラーを修正(しゅうせい)するために、URLオブジェクトを文字列(もじれつ)に変換(へんかん)してから、コンポーネントに渡(わた)す必要(ひつよう)があります。具体的(ぐたいてき)には、URLオブジェクトの toString()
メソッドを呼(よ)び出(だ)すことができます。
以下(いか)は例(れい)です。
const [url, setUrl] = useState<string>("");
useEffect(() => {
if (data.url) {
const url = new URL(data.url);
setUrl(url.toString());
}
}, [data.url]);
これにより、URLオブジェクトが文字列(もじれつ)に変換(へんかん)され、コンポーネントに渡(わた)されるため、エラーが解決(かいけつ)されるはずです。
無事(ぶじ)修正(しゅうせい)できました。ありがとう
よかったです!何(なに)か他(ほか)に問題(もんだい)があれば遠慮(えんりょ)なくお知(し)らせください。
yarn lintで確認(かくにん)すると、もうひとつエラーが出(で)ました。
Using target="_blank" without rel="noreferrer" (which implies rel="noopener") is a security risk in older browsers
対策(たいさく)を教(おし)えて下(くだ)さい
このエラーは、<a>
要素(ようそ)の target
属性(ぞくせい)に "blank"
を指定(してい)するときに、rel
属性(ぞくせい)に "noopener"
か "noreferrer"
を指定(してい)することを求(もと)めています。これは、セキュリティ上(じょう)の理由(りゆう)から、古(ふる)いブラウザでは別(べつ)のウィンドウやタブで開(ひら)いたリンクが、オリジナルのページに悪意(あくい)のあるスクリプトを実行(じっこう)する可能性(かのうせい)があるためです。
修正(しゅうせい)するには、<a>
要素(ようそ)の rel
属性(ぞくせい)に "noopener"
か "noreferrer"
を追加(ついか)する必要(ひつよう)があります。
rel="noreferrer"の追加(ついか)漏(も)れが末尾(まつび)にあることを発見(はっけん)しました。無事(ぶじ)yarn lintも通過(つうか)しました!マジありがとう
よかったです!何(なに)かあればいつでも聞(き)いてください。
InstagramのPOSTとREELを埋(う)め込(こ)めるようになりました!
少(すこ)し時間(じかん)があるときに
埋(う)め込(こ)んだ時(とき)のデザインをカスタマイズできたらいいなと思(おも)います⭐