From 9f85b8379c231bf2cc2f48fede498d6910b32af9 Mon Sep 17 00:00:00 2001 From: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com> Date: Fri, 9 Oct 2026 09:24:16 +0000 Subject: [PATCH] fix(editor): Remove trailing newline from AI Assistant code blocks (no-changelog) (#40731) Co-authored-by: Claude Sonnet 5.5 --- .../messages/useMarkdown.test.ts | 29 +++++++++++++++++++ .../AskAssistantChat/messages/useMarkdown.ts | 9 ++++++ 2 files changed, 38 insertions(+) create mode 100644 packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.test.ts diff --git a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.test.ts b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.test.ts new file mode 100644 index 00000000000..5279ee865a6 --- /dev/null +++ b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.test.ts @@ -0,0 +1,29 @@ +import { useMarkdown } from './useMarkdown'; + +describe('useMarkdown', () => { + const { renderMarkdown } = useMarkdown(); + + it('should not add a trailing newline inside a fenced code block', () => { + const html = renderMarkdown('```\nhttps://example.com/webhook/abc\n```'); + + expect(html).toContain('https://example.com/webhook/abc'); + }); + + it('should keep newlines between lines of a fenced code block', () => { + const html = renderMarkdown('```\nline 1\nline 2\n```'); + + expect(html).toContain('line 1\nline 2'); + }); + + it('should keep the language class on a fenced code block', () => { + const html = renderMarkdown('```js\nconst a = 1;\n```'); + + expect(html).toContain('const a = 1;'); + }); + + it('should keep an intentional blank last line in a fenced code block', () => { + const html = renderMarkdown('```\nline 1\n\n```'); + + expect(html).toContain('line 1\n'); + }); +}); diff --git a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.ts b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.ts index c123f8aa733..4ac7b07c1e0 100644 --- a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.ts +++ b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/messages/useMarkdown.ts @@ -17,6 +17,15 @@ export function useMarkdown() { }, }); + // markdown-it ends fenced code with a newline. Triple-click copy would include it. + const renderFence = md.renderer.rules.fence; + md.renderer.rules.fence = (tokens, idx, options, env, self) => { + tokens[idx].content = tokens[idx].content.replace(/\n$/, ''); + return renderFence + ? renderFence(tokens, idx, options, env, self) + : self.renderToken(tokens, idx, options); + }; + function renderMarkdown(content: string) { try { return md.render(content);