Skip to content

fix(cms): rich text editor "open in new tab" option is stripped on render #537

@jbourdin

Description

@jbourdin

Bug

The Tiptap rich text editor exposes a "target = blank" option for links, but rendered pages do not open the link in a new tab — the target attribute is missing from the final <a> tag.

Root cause

Two layers contribute:

  1. Editor (Tiptap): assets/components/MarkdownEditor.tsx:157

    TiptapLink.configure({ openOnClick: false }),

    No HTMLAttributes are configured, and there's no UI affordance for setting target per-link.

  2. Server-side renderer: src/Service/MarkdownRenderer.php:27-54 configures CommonMark with:

    'allow_unsafe_links' => false,

    This option (combined with CommonMark's default attribute filtering) strips target (and rel) attributes during markdown → HTML conversion.

So even when the editor produces target="_blank", the renderer removes it.

Fix

  1. Configure the Tiptap Link extension with HTMLAttributes: { target: '_blank', rel: 'noopener noreferrer' } for a project-wide default, OR add a per-link UI control in the editor toolbar.
  2. In MarkdownRenderer, switch from CommonMark's stripping behavior to an allow-list that keeps target and rel (consider using league/commonmark's AttributesExtension plus HtmlSanitizer from symfony/html-sanitizer for a safe path forward).
  3. Always emit rel="noopener noreferrer" alongside target="_blank" to avoid window.opener / tab-nabbing.

Files

  • assets/components/MarkdownEditor.tsx:127-198
  • src/Service/MarkdownRenderer.php:27-54
  • src/Service/HomepageRenderer.php:139-176, 240, 275 (callers, for verification)
  • templates/home/blocks/_rich_text.html.twig:10-16 (renders the HTML)

Verification

  1. In the homepage rich-text block or a CMS page, add a link with the "open in new tab" option.
  2. Save and reload the public page.
  3. Inspect the rendered <a> — must contain target="_blank" and rel="noopener noreferrer".
  4. Add a unit test on MarkdownRenderer::render asserting the target attribute is preserved.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions