BETA

Hardcoded help scales. Maintaining it doesn't.

Somewhere in your codebase there is a file called something like strings.ts. In it sits the sentence a user reads when their payment fails. It was written in a hurry, by a developer, eighteen months ago. Nobody on the team has read it since. Several thousand users have.

That file was the right decision when it was created. A tooltip next to the component that needs it requires no infrastructure, no indirection and no second system. For an application with a dozen help texts, maintained by the people who wrote the code, hardcoding is the correct answer and this article is not going to argue otherwise.

What follows is about what changes when help content stops behaving like code.

The correction takes two weeks and touches nothing

Someone in support knows exactly what that payment message should say. They have answered the same ticket forty times. The current sentence explains what went wrong but not what the user should do next, and they can write the better version in about ninety seconds.

What happens next is a ticket, a backlog, a developer picking it up, a branch, a review, CI and a release. Two weeks for one sentence, and at the end of it the product is byte-for-byte identical apart from a string.

None of those steps is expensive on its own. Modern teams make them very cheap. They are simply unrelated to the work being done. Product code should change when the product changes. Help content should change when the explanation changes. Once those two things are on the same release cycle, the slower one sets the pace.

You already moved the strings out

Most teams past a certain size don't hardcode anything. The payment message lives in en.json under a key, translators work on it in a separate tool, and nobody edits a .tsx file to change a sentence.

That solves the first problem properly, and it is worth being clear about it: locale files give you separation from code, stable keys, and a workflow non-developers can use. If that is all you need, stop reading.

What a locale file does not give you is three things.

Composition. Every entry is a leaf. A help panel that needs three paragraphs, one of them shared with a tooltip elsewhere, has nowhere to live in a flat key-value file.

Identity. If the same warning belongs in four places, it exists four times, or it exists once under a key that four call sites happen to reference. Either way, nothing in the file records that they are the same information rather than the same words.

Publication. There is no version you released, as opposed to whatever is currently on main.

Those three are what separate in-app help from interface strings.

Help content is unusually repetitive

A button such as Save is mentioned in dozens of instructions. The same warning belongs before every destructive action. A prerequisite applies to several procedures. A short explanation of a setting is useful in a tooltip, in a dialog, and inside a longer topic.

That repetition is not a defect. Users need information where it is useful, and making somebody leave a task to find an explanation elsewhere would make the help worse, not better.

The problem is maintaining each occurrence as an independent copy. If the same warning is needed in six places, it can appear six times and still have one source.

The goal is not to avoid repetition for the reader. It is to avoid duplication for the people maintaining the source.

Copies eventually disagree

Duplicated help is harmless until something changes.

Suppose Save is renamed Apply. The obvious move is to search for Save and update everything relevant. That mostly works, and the failure mode is instructive: the word itself carries no information about what it represents. Some hits are the UI control. Some are the English verb. You are reading each one to decide.

For longer content it is worse. If a warning has been copied into four topics, nothing connects those four strings except their wording, and once someone has improved one of them, searching for the original text no longer finds all four.

A shared component has identity independent of its current wording. You are not looking for strings that resemble one another; you know which places use the same source. Change the source and every use receives the change.

That matters for writing speed as much as for consistency. Existing warnings, explanations and UI labels become material to search for and insert, instead of prose to write again.

What this actually requires

Less than you would expect. Four properties cover most of it.

Help content lives somewhere it can be edited without touching product code. Pieces that represent the same information are reusable rather than copied. Anything the application requests has a stable identifier. And authors publish a known version, rather than exposing whatever is currently in the editor.

The application's side of the boundary is a request for content by key:

GET /api/deploy/{collection}/billing.payment-status

returning both rendered HTML and plain text. The tooltip uses one, the help panel uses the other. The specific API shape is not the interesting part. The interesting part is that the application depends on the identity of the help content instead of containing the help content.

Two objections worth answering

"So my tooltips go blank when your API is down."

They shouldn't, and any delivery mechanism that fails that way is not usable. Published help is immutable per version, which makes it safe to cache aggressively: fetch at build time, revalidate at runtime, and fall back to the last known payload when a request fails. The failure mode you want is slightly stale, never empty. Treat a help API like a CDN asset, not like a database your render path depends on.

"An author changes a sentence and breaks my layout."

Publishing is a deliberate act, not a save. The version the application receives changes when someone decides it changes, which gives you a preview before and a rollback after. It is still true that content can outgrow the space you gave it. That risk exists with hardcoded strings too, minus the ability to fix it without a deploy.

The threshold is lower than you think

Structured authoring is associated with large documentation departments, and for in-app help that association is wrong.

Ten independent tooltips that rarely change, maintained by the developers who wrote them, do not need any of this. Adding a system because the architecture looks cleaner saves nobody any work.

The calculation changes when the same explanation starts appearing in several places, when a terminology change has to be hunted across the application, or when the people who know what the text should say are not the people who can change it.

At that point the question is not whether source code can store the text. Obviously it can. Hardcoded help scales technically almost without limit. What does not scale is maintaining duplicated content through a software release process, after the content has become a product of its own.


HelpCCMS publishes help content by key over a Deploy API. See the developer documentation.

← Blog