Skip to content

Add UI copy and German translation style guides - #34852

Open
kongo09 wants to merge 3 commits into
element-hq:developfrom
kongo09:language-guide
Open

Add UI copy and German translation style guides#34852
kongo09 wants to merge 3 commits into
element-hq:developfrom
kongo09:language-guide

Conversation

@kongo09

@kongo09 kongo09 commented Aug 27, 2026

Copy link
Copy Markdown
Member

Adds two new documentation guides for translations and UI copy:

  • docs/ui-copy.md — language-independent guidelines for writing Element's interface copy and for how any translation should relate to the English source (voice, grammatical form by position, punctuation, terminology, placeholders/plurals, key renaming).
  • docs/translations/de.md — an English → German translation style guide. The new docs/translations/ directory is intended as the home for future per-language guides.
  • Cross-references added from README.md, docs/translating.md, docs/translating-dev.md and the VitePress sidebar.

Also fixes a pre-existing docs-site bug surfaced while verifying this: the custom link resolver rewrote every relative in-content .md link to a GitHub blob URL missing the docs/ prefix, so cross-doc links (e.g. ./jitsi.md in jitsi-dev.md) rendered as 404s. Links whose target exists within docs/ now pass through to VitePress native resolution; links to repo-root files keep the GitHub fallback. (Separate commit, happy to split it out into its own PR if preferred.)

Verified locally: oxfmt --check passes and vitepress build docs succeeds with the dead-link check enabled.

Checklist

kongo09 and others added 2 commits August 27, 2026 16:33
Add two new documentation guides:

- docs/ui-copy.md: language-independent guidelines for writing
  Element's interface copy and how translations should relate to
  the English source
- docs/translations/de.md: English -> German translation style
  guide; docs/translations/ is the home for future per-language
  guides

Cross-reference them from README.md, docs/translating.md,
docs/translating-dev.md and the VitePress sidebar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The custom link resolver rewrote every relative .md link to a
GitHub blob URL missing the docs/ prefix, so in-content links
between docs pages (e.g. ./jitsi.md in jitsi-dev.md) rendered as
404s. Let links whose target exists within docs/ pass through to
VitePress native resolution; links to repo-root files keep the
GitHub fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread docs/ui-copy.md

Language-independent rules for Element's interface copy: how to write the English source, and how any translation should relate to it.

Applies to Element Web, Element Desktop, shared-components, Element X, Element Call, Element Admin and MAS. Per-language conventions live in the language guides in `docs/translations/` (e.g. the [German translation guidelines](./translations/de.md)).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It only applies to EW/ED et shared components. This repo doesn't rule the other product guidelines

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should nevertheless make clear that language applies cross-product. You cannot change something in Element Web, like renaming a cryptographic concept, without adjusting this in the other places as well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it live in https://github.com/element-hq/element-meta instead? And we keep the exception or EW specialties here?

Comment thread docs/translations/de.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo all of this should be in localazy

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point me to the place where this would live?

Comment thread docs/translations/de.md

These guidelines keep Element's German UI consistent and familiar—aligned with muscle memory from WhatsApp, Signal, Teams, and Slack.

Applies to Element Web, Element Desktop, shared-components, Element X, Element Call, Element Admin and MAS. Where a rule differs by product, it is called out explicitly.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto what?

Comment thread docs/ui-copy.md

- _Admin_ means a **room** admin. "Contact your admin" reads as "ask a moderator here", whatever you intended.
- _Session_ means a Megolm session in crypto contexts, and locally stored login state in others.
- _Client_ means an OAuth client in MAS and admin surfaces.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client also means other matrix clients in our translations

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point me to an example?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at the strings.

  • There are 13 strings with the word client in EW and they all refer to the app.
  • In EX there are zero strings with the word client. This is all app.
  • MAS has 5 strings and I need to figure out which one of these are actually apps
  • Admin has 5 strings and makes the important distinction in one of the strings:

Applications are OAuth 2.0 clients that users sign in to.

Proposal: I'll tidy up this string in a better way, so that

  • App or Application is the consistent word for the software a user runs to chat
  • Client is only used in the technical context of OAuth

Does that make sense to you?

@t3chguy t3chguy Aug 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

App or Application is the consistent word for the software a user runs to chat

I wouldn't consider a website an "app" - in the context of Element Web

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Element calls the web application "app"

image

The browser itself calls something like Element an app

image

Microsoft calls the Teams web app an app

image

The term "client" is a technical term, as in server-client API. Good for Matrix. Not good for end users.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The browser itself calls something like Element an app

Yes, it is an app if you install the PWA "Progressive Web App" - hence it says "App available"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we're all aligned now?

Comment thread docs/ui-copy.md

- **Name variables for the translator, not for the programmer.** `recipient` tells a translator nothing — is it a person, an email address, a user ID? `recipientEmailAddress` does. The variable name is often the only context a translator gets.

- **Before adding a string, check whether it already exists** in a related project. Reusing a shared string is better than a near-duplicate — but if the existing one is _wrong_, fix it rather than working around it, or the divergence spreads.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same words have different meaning in different use case. Also the key is also kind of a path of where the translation is used and also a sense.

I agree to use common string for actions which are vastly used and without ambiguity.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a todo here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, i don't understand, what todo?

Comment thread docs/ui-copy.md

| Change | Rename the key? |
| ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| **The meaning changes** — the string now says something different | **Yes.** Renaming forces every language to retranslate, which is what should happen |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't agree:

  1. You can force the re-translation in localazy without changing the key
  2. We have a lot of key like: example_of_a_dialog|description. Even if the meaning change, the key is still valid. Forcing the re-translation in localazy is enough

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, you can force from localazy. Changing the key is not necessary. I'll remove this

Comment thread docs/ui-copy.md

- **When referencing another system's UI** — iOS Settings, Android, another Element app — match that system's wording exactly, in every language. Some names (Apple's alert-tone names) are untranslated in every locale.

- **Name variables for the translator, not for the programmer.** `recipient` tells a translator nothing — is it a person, an email address, a user ID? `recipientEmailAddress` does. The variable name is often the only context a translator gets.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the dev, should be in translating-dev.md

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What rule would you propose to distinguish what goes into what file? My impression was that the dev file is less about content but more about the dev mechanics, the project, the process. In that case, above language advise would sit here and not there.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point

Comment thread docs/ui-copy.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This guide is for developers or translators?

It seems to combine technical guidelines (how our internalization framework works) and wording guidelines(which are provided by the design team in Figma)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be for whoever writes initial language strings. That can be a designer, a product manager, a contributors, a developer, etc... It should not contain technicalities, like how placeholders work or what the process is overall, but guide on UI copy content.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay make sense thanks

Comment thread docs/ui-copy.md

- **Prefer full repeated sentences over shared fragments.** Several near-identical strings that differ by a word or two look like waste, but they translate faster and more accurately than fewer strings assembled from pieces. This is the opposite of the instinct that serves you well in code.

- **Use the framework's plural mechanism, never an `if`.** Choosing between a singular and a plural string in code assumes two forms; some languages have up to six. Pass the count and let the translation declare its own forms.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for the dev, should be in translating-dev.md

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree

Comment thread docs/ui-copy.md

## 10. Working practice

- **Run the machine checks whenever the files change.** Key coverage, placeholder and markup parity, plural completeness, whitespace, and translation-identical-to-source are all mechanical, cost seconds, and catch regressions that reading does not.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it running the tests? I don't think we have anything to catch plural completeness?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point. I've run my own tooling when I worked through the clean-up which did all of the above and discovered loads of problems. But we don't have that in CI. I'll reword.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-Task Tasks for the team like planning

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants