Skip to content

YouTube Shorts render in a 16:9 frame (pillarboxed) on web and self-hosted #1271

Description

@feruzm

YouTube Shorts are vertical (9:16) but render in a 16:9 frame on every surface, so the clip plays pillarboxed between two wide black bars. Sibling of #1269, which fixed the 3Speak and Truvvl cases; this one could not be fixed the same way because the orientation signal does not exist.

Why the #1269 approach does not apply

3Speak reports its orientation at runtime (3speak-player-ready postMessage), so a listener can class the container. YouTube sends nothing comparable, and the embed URL for a Short is identical to a normal video (/embed/<id>). The only signal is the source URL the author posted, which is lost during rendering: a.method.ts matches YOUTUBE_REGEX (which already accepts a /shorts/ path), extracts the 11-char id, then strips href. Downstream, nothing can tell a Short from a landscape video.

Where it breaks

  • packages/render-helper/src/methods/a.method.ts — the YouTube branch emits markdown-video-link markdown-video-link-youtube for a Short exactly as for a normal video, with no orientation marker.
  • apps/web/src/features/post-renderer/ecency-renderer.scss and apps/self-hosted/src/styles/blog-markdown.css — both size .markdown-video-link-youtube at a fixed 16:9.

Naming trap for whoever picks this up

.youtube-shorts-iframe already exists and is not shorts-specific: youtube-video-extension.tsx:39 puts it on the iframe of every click-to-play YouTube player, and the SCSS treats it as a fill-the-container rule. Do not reuse that class as the orientation marker.

Sketch

  1. In a.method.ts, detect the /shorts/ path on the source href and emit a modifier (e.g. markdown-video-link-youtube-portrait) alongside the existing classes, before href is removed. Note YOUTUBE_EMBED_REGEX also matches /shorts/ for author-pasted iframes, so iframe.method.ts needs the same treatment to reach iframe.portrait-embed or an equivalent.
  2. Add 9:16 rules keyed on that modifier in both consumers, reusing the ratios and max widths from the Self-hosted blog: vertical (9:16) videos render inside a forced 16:9 frame #1269 work so all portrait video looks consistent.
  3. Per the provider contract, both authoring paths need covering: a bare link (anchor + wrapper) and a pasted <iframe> (bare iframe, no wrapper).

Caveat

This only catches Shorts posted with a /shorts/ URL. The same video shared as watch?v= or youtu.be/ carries no hint and stays 16:9. Accepting that partial fix seems right; the alternative is a server-side oEmbed lookup for every YouTube link, which is a much larger change and a per-render network dependency.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions