埋め込みサイトが「ディスカッションの読み込み中」で固まっている

こんにちは。NextJS Web アプリに Discourse を埋め込もうとすると、この問題が発生します。同じエラーに触れている既存のスレッドで回答を探してみましたが、私の問題の解決策を見つけることができませんでした。

埋め込みコードは次のようになります。

<script id="discourse" type="text/javascript" data-nscript="afterInteractive">DiscourseEmbed = {
              discourseUrl: 'https://qanvast.discourse.group/',
              discourseEmbedUrl: 'https://web-uat.qanvast.com/sg/interior-design-singapore/forefront-interior-the-alcove-26226?image=769596',
              // className: 'CLASS_NAME',
            };

            (function() {
              var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
              d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
              (document.getElementsByTagName('head')[0]
              || document.getElementsByTagName('body')[0]).appendChild(d);
            })();</script>

フロントエンドでは、「Loading Discussions…」でスタックしたままになります。最初は CSP に関係があると思いましたが、ドメインを埋め込み許可リストに追加しました。コンソールログやネットワーク呼び出しにはエラーは表示されません。

数時間この問題で立ち往生しているので、どんな助けでも感謝します。

「いいね!」 1

こんにちは、@Edrian_C_Bertulfo さん、ようこそ :wave:

このトピックに従いましたか?これはその方法ですが、NexJSウェブアプリで機能するかどうかはわかりません…

こんにちは、リリーさん!

お返事ありがとうございます。投稿にあった指示に従いましたが、「ディスカッションを読み込み中…」という問題が無限に続いています。

「いいね!」 1

わかりましたか?

Next.js でも同様の問題が発生しています。トピックが作成される前の最初の読み込み時に「ディスカッションを読み込み中」でスタックします。リロードすると、コメント/ディスカッションを開始するが表示されるため、トピックは正常に作成されますが、読み込み状態が更新されません(コメントボックスが表示された更新状態を表示するにはリロードする必要があります)。

トピックが作成されたことを通知するコールバックなどがあると良いのですが、iframe でそれが可能かどうかはわかりません。

うーん、トピックが作成された後でも、実際にはまったく読み込まれません…
少なくとも私には。

何かヒントはありますか?

次のアプリでこれを用意しました。以前説明したように動作します。更新を押す必要があります。動作するか教えてください。

時々、数回更新したり、しばらく待ってから更新したりして、「ディスカッションを読み込み中」メッセージをスキップする必要があります。

<DiscourseComments
          discourseUrl="https://discourseurl.com/"
          discourseEmbedUrl={embedUrl}
          username="system"
        />

コンポーネント:

"use client"

import { useEffect, useRef } from "react"

/**
 * Discourseコメントをウェブサイトに埋め込むためのReactコンポーネント
 *
 * @param {Object} props - コンポーネントのプロパティ
 * @param {string} props.discourseUrl - DiscourseインスタンスのURL(末尾のスラッシュを含む)
 * @param {string} [props.discourseEmbedUrl] - 現在のページのURL(トピックの自動作成用)
 * @param {number} [props.topicId] - 既存のDiscourseトピックのID(discourseEmbedUrlの代替)
 * @param {string} [props.username] - トピック作成時のユーザー名
 * @param {string} [props.className] - 埋め込みに追加するCSSクラス名
 * @param {string} [props.referrerPolicy] - iframeのReferrer Policy
 */
export default function DiscourseComments({
  discourseUrl,
  discourseEmbedUrl,
  topicId,
  username,
  className,
  referrerPolicy = "no-referrer-when-downgrade",
}) {
  const initialized = useRef(false)

  useEffect(() => {
    // 重複初期化の防止
    if (initialized.current) return
    initialized.current = true

    // 必須プロパティの検証
    if (!discourseUrl) {
      console.error("DiscourseComments: discourseUrl は必須です")
      return
    }

    if (!discourseEmbedUrl && !topicId) {
      console.error("DiscourseComments: discourseEmbedUrl または topicId のいずれかを提供する必要があります")
      return
    }

    // Discourse埋め込みの設定
    const config = {
      discourseUrl,
      discourseReferrerPolicy: referrerPolicy,
    }

    if (discourseEmbedUrl) {
      config.discourseEmbedUrl = discourseEmbedUrl
    }

    if (topicId) {
      config.topicId = topicId
    }

    if (className) {
      config.className = className
    }

    // グローバルなDiscourseEmbedオブジェクトを設定
    window.DiscourseEmbed = config

    // Discourse埋め込みスクリプトをロード
    const script = document.createElement("script")
    script.type = "text/javascript"
    script.async = true
    script.src = `${discourseUrl}javascripts/embed.js`
    document.head.appendChild(script)

    // クリーンアップ
    return () => {
      document.head.removeChild(script)
      delete window.DiscourseEmbed
    }
  }, [discourseUrl, discourseEmbedUrl, topicId, className, referrerPolicy])

  return (
    <>
      <div id="discourse-comments"></div>
      {username && <meta name="discourse-username" content={username} />}
    </>
  )
}