WeblateOrg / WeblateOrg/weblate
MDX: inline placeholders ({1}, {2}) are written into the translated file instead of the original markup
- Dominant language
- Python
- Stars
- 6.1k
- Forks
- 1.4k
- Avg merge
- 9h 53m
- Merged PRs (30d)
- 395
Description
### Describe the issue
File format: MDX (monolingual, template is the English file). No add-ons installed.
With the default file format parameters, Weblate shows inline markup as numbered placeholders in the editor. A unit like this English source:
```
Starting with backend version 6.32.0, the EPG update event is supported.
[Read about events](../events/index.mdx)
```
is presented to translators as `...supported.{1}\` and `[Read about events]{2}`. That part works well.
The problem is on the write side. When a translation for such a unit is committed, the literal `{1}` and `{2}` tokens are written into the translated MDX file instead of being substituted back with the original markup. The written file contains:
```
- Starting with backend version 6.32.0, the EPG update event is supported.{1}\
[Read about events]{2}
```
In MDX, `{1}` is a JSX expression, so the written file no longer compiles. In our case eslint-mdx fails with `@typescript-eslint/no-unused-expressions` on every affected line, and the Docusaurus build rejects the file.
Setting the file format parameter `md_no_placeholders=True` avoids the problem, so we are using that as a workaround. The placeholder editing experience is nicer for translators, so it would be good to have the substitution fixed.
### I already tried
- [x] I've read and searched [the documentation](https://docs.weblate.org/).
- [x] I've searched for similar filed issues in this repository.
### Steps to reproduce the behavior
1. Create a monolingual MDX component with default file format parameters (placeholders enabled). The template file needs a paragraph that combines `
` with a Markdown link, for example a list item like the one quoted above.
2. Translate that unit for any target language (manually, or via automatic translation from TM).
3. Commit the component repository so Weblate writes the translation file.
4. Open the written file: the placeholder tokens `{1}` and `{2}` appear literally where `
` and the link destination should be.
### Expected behavior
On write, placeholders are replaced with the original markup they stand for, so the output file stays valid MDX and matches what a translator saw as immutable markup.
### Screenshots
_No response_
### Exception traceback
_No response_
### How do you run Weblate?
Docker container
### Weblate version
2026.8.1
### Weblate deploy checks
```
SystemCheckError: System check identified some issues:
CRITICALS:
?: (weblate.E012) The server e-mail address should be changed from its default value
HINT: https://docs.weblate.org/en/weblate-2026.8.1/admin/install.html#production-email
?: (weblate.E013) The "From" e-mail address should be changed from its default value
HINT: https://docs.weblate.org/en/weblate-2026.8.1/admin/install.html#production-email
INFOS:
?: (weblate.I021) Error collection is not set up, it is highly recommended for production use
HINT: https://docs.weblate.org/en/weblate-2026.8.1/admin/install.html#collecting-errors
?: (weblate.I028) Backups are not configured, it is highly recommended for production use
HINT: https://docs.weblate.org/en/weblate-2026.8.1/admin/backup.html
System check identified 4 issues (1 silenced).
command terminated with exit code 1
```
Contributor guide
Research direction
Start by locating Weblate's MDX file-format implementation and its write-side placeholder handling, then reproduce the issue with the described MDX component using default parameters. Verify the behavior with md_no_placeholders disabled and enabled; done means committed translations restore the original markup instead of writing literal {1} and {2} tokens, while existing placeholder editing remains usable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- localization
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 67/100