コンテンツローカライズでは、翻訳済み投稿にS3 CDN URLではなく生のR2バケットURLが使用されています

こんにちは、

Cloudflare R2 を S3 互換ストレージとして使用し、Discourse AI の翻訳機能とコンテンツローカライゼーションを併用した場合、翻訳された投稿の内容には設定済みの s3_cdn_url(カスタムドメイン)ではなく、R2 バケットのエンドポイント URL がそのまま保存されます。これにより、翻訳版を表示するすべてのユーザーで画像が壊れて表示される問題が発生します。

環境

  • Discourse: latest
  • Cloudflare R2 は S3 互換ストレージとして設定済み
  • s3_cdn_url: https://files.mydomain.com
  • s3_use_cdn_url_for_all_uploads: 有効
  • コンテンツローカライゼーション + Discourse AI 翻訳: 有効

再現手順

  1. カスタムドメイン(s3_cdn_url)付きで Cloudflare R2 を設定する
  2. コンテンツローカライゼーションと AI 翻訳を有効にする
  3. 画像を含む投稿を作成する
  4. AI 翻訳がローカライズ版を生成するのを待つ
  5. 言語を切り替える — 翻訳版内の画像が壊れている

観察された動作

翻訳後のコンテンツには、https://files.mydomain.com/original/1X/ の代わりに以下のような URL が含まれています:

//files.myendpoint.r2.cloudflarestorage.com/original/1X/

関連するバグ: Chat thumbnails bypass s3_cdn_url & use raw S3 bucket URLs

一時的な修正方法として、リマップを行うか、以下のテーマコンポーネントを使用できます:

import { apiInitializer } from "discourse/lib/api";

export default apiInitializer("1.8.0", (api) => {
  const badDomain = "files.myendpoint.r2.cloudflarestorage.com";
  const goodDomain = "files.mydomain.com";

  function fixImages() {
    document.querySelectorAll(`img[src*="${badDomain}"]`).forEach(img => {
      img.src = img.src.replace(badDomain, goodDomain);
    });
    document.querySelectorAll(`img[data-src*="${badDomain}"]`).forEach(img => {
      img.dataset.src = img.dataset.src.replace(badDomain, goodDomain);
    });
    document.querySelectorAll(`img[data-large-src*="${badDomain}"]`).forEach(img => {
      img.dataset.largeSrc = img.dataset.largeSrc.replace(badDomain, goodDomain);
    });
  }

  api.decorateCooked(() => fixImages(), { id: "fix-r2-translated-images" });
  api.onPageChange(() => fixImages());
});

私はこれについてあまり確信がありません。私たちのサイトでは、オブジェクトストレージとバックアップ用にCloudflare R2バケットを使用しており、AI翻訳で複数言語に対応しています。画像はすべて正しく読み込まれています。

例えば:

英語

ドイツ語

ロシア語

ポルトガル語

はい、私のテストでは3〜5枚の画像をアップロードしています。しかし、期待通りに動作するのは1〜2枚だけです。