Problem/Motivation
When embedding media via Media oEmbed on multilingual Drupal sites, the sandboxed iframe page (/[langcode]/media/oembed?...) renders without a lang attribute on its element. Without this attribute, assistive technologies cannot determine the language of the page and may apply the wrong speech engine.
This triggers accessibility audit failures referencing WCAG SC 3.1.1 Language of Page (Level A).
Steps to reproduce
- Set up a multilingual Drupal site (e.g. English + French).
- Install the Media module.
- Create content with an embedded YouTube video via the Media module (Remote video / oEmbed).
- Visit the content page in a non-default language (e.g.
/fr/...). - Open the oEmbed sandboxed page directly (
/fr/media/oembed?...). In Edge, you can get the URL by inspectingiframeelement on the node page with DevTools and finding the#documentelement within. Right-click the URL for#documentand choose "Open in new tab". - Inspect the
<html>tag: nolangattribute is present. - Run an accessibility audit: a missing lang attribute error is reported on the oEmbed page.
Current behavior
media-oembed-iframe.html.twig renders:
<html>
<head>...</head>
<body>
<iframe src="https://www.youtube.com/embed/ID?feature=oembed"></iframe>
</body>
</html>The template renders with no lang attribute.
Expected behavior
The template should render (or the appropriate language code for the current content language).
Proposed solution
Add a preprocess_media_oembed_iframe hook that reads the current content language and passes it as langcode to the template. Apply it via lang="{{ langcode }}" on the element.
Additional notes
- The media-oembed-iframe.html.twig template does not set a lang attribute on at all, which is also an issue independently of YouTube: any text inside the oEmbed page is language-less from an assistive technology perspective.
- This issue is related to but distinct from #3085545 (inner iframe missing title attribute) and #3152111 (duplicate iframe titles).
- The outer Drupal iframe (rendered by OEmbedFormatter) also has no lang attribute, though fixing the oEmbed page itself seems more impactful.
- Tested on Drupal 11.3.8, confirmed on a production multilingual site.
Issue fork drupal-3593533
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
gwenweb commentedComment #4
quietone commentedHi, Issues for Drupal core should be targeted to the 'main' branch, our primary development branch. Changes are made on the main branch first, and are then back ported as needed according to the Core change policies. This is also mentioned on the version section of the list of issue fields documentation. The version the problem was discovered on should be stated in the issue summary Problem/Motivation section. Thanks.
Comment #5
gwenweb commentedComment #6
gwenweb commentedThank you for the guidance! I've updated the Issue Summary to mention that the problem was discovered on Drupal 11.x.
I also noticed the MR was incorrectly based (the branch included all of Drupal core's files instead of just the fix). I've rebased it properly — the MR now contains a single commit with only 2 files changed:
Apologies for the noise, and happy to adjust anything further.
Comment #7
kentr commentedThanks for reporting this.
I have a question about the expected result.
In Microsoft Edge / macOS with the MR, I see
<html lang="fr">in the page source, but the video UI is still in English. For example, the tooltip that appears when hovering the pointer over the Play button says "Play video".When I add French as a language and put it at the top of the list in the browser settings, the video UI is in French (I think it's French :-).
And the video UI stays in French when I go back to the English version of the page.
So, it seems that the new
langattribute has no effect on what YouTube serves.It also concerns me that the actual content served by YouTube can be in a different language than what the
langspecifies. Doesn't that still fail SC 3.1.2 Language of Parts (Level AA) (and maybe also SC 3.1.1 Language of Page (Level A), since this is a self-contained document inside theiframe)?Edit: Is it expected that the served media will actually be in the language specified by the
langattribute?Comment #8
kentr commentedI added to the steps to reproduce, formatted the IS a little, and tagged for SC 3.1.2.
Comment #9
gwenweb commentedThank you for testing this so thoroughly, kentr — and for the very precise question.
To be honest: no, I did not expect the lang attribute alone to change what YouTube serves. The lang attribute on tells assistive technologies (screen readers) what language this Drupal-generated wrapper page is in, so they can apply the correct speech engine. It has no effect on YouTube's player UI, which is driven by the hl URL parameter, the user's browser locale, or their Google account settings.
So this MR only addresses WCAG SC 3.1.1 (Language of Page) — not SC 3.1.2. You're right that SC 3.1.2 would require passing hl to the YouTube embed URL, which is a separate and more complex change.
I may have caused confusion by mentioning SC 3.1.2 in the issue summary. Would it make sense to narrow this issue to SC 3.1.1 only, and open a separate issue for the hl parameter? I'm happy to update the summary accordingly.
Comment #10
kentr commented@gwenweb
Sounds good to me. I got an error from Accessibility Insights about the missing
langattribute on the sandboxed page.After you update the issue summary, I want to get signoff from another accessibility team member.
Comment #11
kentr commentedI meant to put this to Needs work, not Needs review.
Comment #12
gwenweb commentedComment #13
kentr commentedThanks @gwenweb.
So, I found this Accessibility Conformance Testing (ACT) rule which leads me to believe that it's not technically a failure of SC 3.1.1. However, it says in the last sentence that it still may be a problem.
I narrowed the issue title to apply only to the
htmlattribute.Comment #14
kentr commentedI added to the quote in my previous comment.
Comment #15
kentr commentedNote: That link / quote is from the Accessibility Conformance Testing (ACT) rule to test 3.1.1: Language of Page (Level A).
That would explain why Accessibility Insights doesn't throw an error for the main page: the
htmlin question is not the top-level browsing context.@gwenweb, was this from a manual audit? I'm curious to hear the auditors' thoughts on the ACT rule.
Comment #16
kentr commentedBTW, my noting that this may not technically be a failure of SC 3.1.1 was not a statement that the change shouldn't still be made.
Comment #17
gwenweb commentedThank you for asking !
The audit was conducted by https://accessibility.belgium.be/, the Belgian federal authority for digital accessibility. Their finding was:
"The language of the
element does not match the language of the current page. The lang attribute value of the YouTube player does not follow the language of the current page. [...] This can be modified via the YouTube IFrame Player API settings (parameter: hl)." If I'm reading this correctly, their report seems to be about the YouTube player language (the hl parameter) — which would be closer to the SC 3.1.2 concern you already identified. But I may be misinterpreting what they flagged exactly. As for the ACT rule, I honestly hadn't considered that angle. If the sandboxed page doesn't technically fall under SC 3.1.1 because of its nested browsing context, then I'm not sure what the right framing for this fix is — maybe just a best-practice improvement rather than a strict WCAG fix? I still need to open the follow-up issue for the hl parameter — I'll do that once this one moves forward.Comment #18
kentr commentedYeah, that sounds like it's specifically related to the player itself (the HTML served by YouTube that constitutes the player).
What's interesting is that I can create a media item in Drupal with
&hl=frin the URL, and YouTube still gives me an English version until I change the browser language preferences.Comment #19
gwenweb commentedThat's a really interesting finding — if &hl=fr doesn't reliably change the player language and YouTube ultimately defers to the browser preference, then the SC 3.1.2 fix may be less straightforward than it seemed.
I'll leave it to the accessibility team to decide whether this MR still makes sense as a standalone fix for the wrapper page.