covid19
covid19 copied to clipboard
実際にサイトにiframe埋め込みすると英語にならない。他
起こっている問題 / The Problem
- 英語版のiframeの埋め込みコードをコピーしてサイトに貼り付けると日本語で表示される。
- ローディングも表示される。
- URLに直接アクセスすると、ローディングは表示されず、英語で表示される。
スクリーンショット / Screenshot

都営地下鉄の利用者数の推移 日本語<br/>
https://stopcovid19.metro.tokyo.lg.jp/cards/predicted-number-of-toei-subway-passengers?embed=true<br/>
<iframe width="560" height="315" src="https://stopcovid19.metro.tokyo.lg.jp/cards/predicted-number-of-toei-subway-passengers?embed=true" frameborder="0"></iframe><br/>
都営地下鉄の利用者数の推移 英語<br/>
https://stopcovid19.metro.tokyo.lg.jp/en/cards/predicted-number-of-toei-subway-passengers?embed=true<br/>
<iframe width="560" height="315" src="https://stopcovid19.metro.tokyo.lg.jp/en/cards/predicted-number-of-toei-subway-passengers?embed=true" frameborder="0"></iframe><br/>
期待する見せ方・挙動 / Expected Behavior
- iframeに埋め込んだ場合も直接アクセスした時と同じ動作になる。
- ローディングが表示されない。
- サイドナビゲーションが表示されない。
- 翻訳されて表示される。

起こっている問題の再現手段 / Steps to Reproduce
- https://stopcovid19.metro.tokyo.lg.jp/enにアクセス
- 埋め込みコードをコピー
- 自分のサイトに貼り付け
- 自分のサイトにアクセス
動作環境・ブラウザ / Environment
- macOS
- Chrome
私だけでしょうか?
再現しますね https://jsfiddle.net/kzhrk/qwadz0vn/1/
localhostでnuxtのpages内に埋め込むと意図した動きになるので、CORSが怪しいです。

↑のjsfiddleのコード、私の手元だとChrome だと英語にならず日本語、Safari だと英語になります。
↑のjsfiddleのコード、私の手元だとChrome だと英語にならず日本語、Safari だと英語になります。
するとChromeの言語設定の問題ですかね。
Chromeで言語設定を英語に変えたら英語になりました!
国際化に使っているnuxt-i18nが初回の言語選択にCookieを参照、Cookieが参照できなければブラウザの言語設定(navigator.language)を参照しています。 別ドメインに置かれたiframeではSame-site CookiesでCookieの取得に失敗してブラウザの言語設定を参照しているのが原因のようです。 https://github.com/nuxt-community/nuxt-i18n/blob/2a17c99145c280b7304691396b8e009056054ae5/src/plugins/main.js#L238
対策としては
- Same-site Cookiesの設定をする(サーバの実装が必要なので非現実的)
- URLに
embed=true
のクエリパラメータがあるときにURLのパスから言語を判定してthis.$root.$i18n.setLocale
を実行する
あたりでしょうか。 後者でPRつくってみます。
URLにembed=trueのクエリパラメータがあるときにURLのパスから言語を判定してthis.$root.$i18n.setLocaleを実行する
いろいろ試してみたんですがiframe内のNuxt内部で
- nuxt-i18nでCookieの取得に失敗
- ブラウザの言語設定(ja)を取得してlocaleに指定
- vue-routerのパス解決(/en -> /)
- 各コンポーネントのマウント
の順番になるのでURLのパスの取得ができませんでした 😢
別の対策として埋め込み用コードのiframe[src]
にlang=en
のような言語設定用のクエリパラメータを付与する方法でPRつくります。
ブラウザの言語設定のページを参照してからクエリパラメータの言語ページに遷移する形になってしまいますが、他に対策あればアドバイスください。
調査ありがとうございます。私ではさっぱりでした。
ブラウザの言語設定を取得するところをURLでの言語指定がない時に絞るのはどうでしょうか? 日本語も「/ja」にする必要はあるかもしれません。
そもそも埋め込みして見せたい人たちにとって、どちらが良いんですかね。
- 自分の意図した通りの言語で表示される
- 相手の言語設定に合わせて表示される
埋め込みだと言語選択ツールがつかないのもよくないのかもしれません。
アドバイスありがとうございます 🙏
ブラウザの言語設定を取得するところをURLでの言語指定がない時に絞る
ブラウザの言語設定を取得しているのが外部モジュールで、このリポジトリ内のコードでは手が出せないところなんですよね… 上記の対応をするであれば、
- 外部モジュールのnuxt-i18nにオプション追加のPRを出してマージされる
- nuxt-i18nをforkして独自モジュールとして使用する
となるかなと思います。どちらもあまり現実的ではありません… 🤔
埋め込みだと言語選択ツールがつかないのもよくない
たしかにiframe内に言語選択ツールがある方がユーザフレンドリーになる気がします 👍 そして現状の実装だと、ユーザのブラウザ言語設定がiframe表示時の初期値になっているのでユーザにとっては今の挙動がベストなのかもしれないです。
iframe[src]
にlang=en
のような言語設定用のクエリパラメータを付与
上記の対応ではなく、多言語対応選択メニューをiframe内に表示する対応をしようかと思いますがどうでしょうか。
スミマセン、ちょっとだけ横入りさせてください。
現状、nuxt.config.ts
の下記の部分で、外部モジュール nuxt-i18n
が自ら設定した Cookie、あるいはプラウザ・ネイティブ言語設定を nuxt-i18n
が(他意なく)捕捉・反映するため、<iframe>
コンテンツの URI に言語識別子を持っていたとしても(英語ページ URI の想定 https://stopcovid19.metro.tokyo.lg.jp/en/ )、<iframe>
コンテンツが日本語 で表示されてしまう、という問題と理解しました。
※誤りがありましたら、お知らせください。
たとえば、日本語ページについても http://hostname/ja/ のように言語識別子を URI に含めてみるというアイディアは機能しそうでしょうか?
generate: {
fallback: true,
routes() {
const locales = ['ja', 'en', 'zh-cn', 'zh-tw', 'ko', 'ja-basic']
const pages = [
'/cards/details-of-confirmed-cases',
'/cards/details-of-tested-cases',
'/cards/number-of-confirmed-cases',
'/cards/number-of-confirmed-cases-by-municipalities',
'/cards/attributes-of-confirmed-cases',
'/cards/number-of-tested',
'/cards/number-of-inspection-persons',
'/cards/number-of-reports-to-covid19-telephone-advisory-center',
'/cards/number-of-reports-to-covid19-consultation-desk',
'/cards/predicted-number-of-toei-subway-passengers',
'/cards/agency'
]
const routes: string[] = []
locales.forEach(locale => {
pages.forEach(page => {
if (locale === 'ja') {
routes.push(page)
return
}
const route = `/${locale}${page}`
routes.push(route)
})
})
return routes
}
},