[Bug]: Inline code typed on dead-key keyboard layouts renders literally (non-ASCII grave instead of U+0060)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Before submitting
- I searched existing issues and did not find a duplicate. (Searched:
backtick,inline code,grave,dead key,U+02CB,keyboard layout,markdown render,code span— closest are #2189 / #2706, which are about hotkeys on non-English layouts, not typed text.) - I included enough detail to reproduce or investigate the problem.
Area
apps/web
Steps to reproduce
On a keyboard layout where the grave/backtick is a dead key (e.g. German, French):
- In the chat composer, type an inline-code span:
`inline code` - Send the message.
Layout-independent way to confirm the rendering half: send a message whose graves are U+02CB instead of U+0060 (paste ˋinline codeˋ).
Expected behavior
The sent user message renders inline code as a styled inline-code span — the same as it would in an assistant message.
Actual behavior
The backticks are shown literally and no code span is rendered.
This is an input/data bug, not a renderer bug. The graves in the stored message text are not ASCII U+0060 but a look-alike — most likely U+02CB MODIFIER LETTER GRAVE ACCENT (possibly U+FF40 / U+2035 depending on layout). CommonMark only treats U+0060 as a code-span delimiter, so it correctly renders the look-alikes as plain text.
Verified by rendering the exact string through the app's own markdown pipeline (react-markdown + remark-gfm + remark-breaks, using the repo's node_modules):
| Input | Output |
|---|---|
`inline code` (U+0060) |
<p><code>inline code</code></p> ✅ |
ˋinline codeˋ (U+02CB) |
<p>ˋinline codeˋ</p> ❌ literal |
User and assistant messages share the same renderer, so assistant messages are unaffected (models emit real U+0060).
The non-U+0060 grave is most likely introduced in the composer's IME/dead-key handling, which passes composed input through unchanged — see the insertCompositionText early-return at apps/web/src/components/ComposerPromptEditor.tsx:1270. (The renderer behavior above is verified; this entry point is strongly suspected but not yet proven — confirming the stored codepoint, e.g. text.codePointAt(i).toString(16), would pin it down.)
Impact
Minor bug or occasional failure
(Globally minor, but frequent for affected users: on a dead-key layout every inline-code span typed in chat is broken.)
Version or commit
main @ 3bdaa6e1
Environment
Linux. Layout-dependent — reproducible on any OS where the grave/backtick is a dead key (German, French, etc.).
Workaround
Use a keyboard layout without a dead-key grave, or paste a real U+0060 backtick into the composer.
Suggested fix (optional)
Normalize a dead-key-originated grave to U+0060 at the input boundary (the composition handler), rather than a global content rewrite. Please avoid blanket-rewriting U+02CB in message content — it's a legitimate character (Bopomofo 4th-tone mark, phonetic tone notation), so only the keystroke intended as a backtick should be corrected.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/web/src/components/ComposerPromptEditor.tsx at the insertCompositionText early return around line 1270, and confirm which code point is stored for a dead-key grave. Reproduce the input and compare the app's markdown rendering for U+0060 and the look-alike character. Done means only the intended dead-key backtick becomes U+0060 and inline code renders correctly without rewriting legitimate content.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100