Hardcoded Label Instead Of A Resource Bundle Reference

ID

html.labels_defined_resource_bundle

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Html

Tags

best-practice, reliability

Description

Reports a template component whose label is hardcoded text where a resource-bundle reference belongs.

This rule ships disabled. Every finding it produces is true by the rule’s own definition, but on a project that has deliberately not internationalised its views it fires once per label — and whether to internationalise is the project’s decision, not this catalogue’s. Switch it on for a project that has committed to a resource bundle, where the findings are the labels that were missed.

Two guards keep it narrow when it is on.

It only looks at namespaced component elements. A literal in plain HTML — <label>Customer name</label>, <img alt="Logo"> — is not evidence of anything, because the page may have no bundle mechanism at all, and reporting it would fire on every static page ever written. A namespaced element such as <h:outputLabel> or <p:tab> is different: the file demonstrably uses a component library, so the machinery for externalising its text is present and the decision not to use it is a decision. Elements in the logic, formatting and templating namespaces (c:, fn:, fmt:, jsp:, sql:, ui:) are skipped, because their attributes carry configuration rather than rendered text.

The value must read as human-readable text. Not reported are values carrying a template expression in any dialect (that is the correct form), values shorter than three characters or with fewer than two letters, values containing a character no label contains (< > { } = | \ / : ; # & $ * ~ ^ @), and single tokens carrying a dot or an underscore, which are filenames, identifiers or bundle keys rather than prose.

At most one finding is emitted per element: once the author is looking at the tag, naming a second attribute on it adds nothing.

Rationale

<h:form>
  <h:outputLabel for="customer" value="Customer name" />
  <h:inputText id="customer" title="Enter the full legal name" />
  <h:commandButton value="Place order" action="#{orderBean.place}" />
  <h:outputLabel for="ref" value="#{msg.orderReference}" />
</h:form>

A label baked into the markup cannot be translated, and cannot be corrected without a redeploy — a typo in a button caption becomes a release.

The form above shows the failure that matters most, which is not the absence of translation but its partiality. The page already resolves orderReference from a bundle, so it is a translated page; three of its four strings are not. Rendered in another language it comes out half in the user’s language and half in the developer’s. That state is invisible to everyone who reads the application in its original language, including the author, the reviewer and the tests — the page looks correct in development and is broken only for the users who cannot report it clearly.

The same text also tends to be duplicated. A caption written in four views diverges in three of them; a caption resolved from a bundle key is corrected once. And an untranslated string is untranslatable by the people equipped to do it: a translator works from the bundle, and never sees a string that is not in it.

Remediation

Move the text into the resource bundle and reference it by key.

<h:form>
  <h:outputLabel for="customer" value="#{msg.customerName}" />
  <h:inputText id="customer" title="#{msg.customerNameHint}" />
  <h:commandButton value="#{msg.placeOrder}" action="#{orderBean.place}" />
  <h:outputLabel for="ref" value="#{msg.orderReference}" />
</h:form>

With the bundle declared for the view — through <f:loadBundle>, a <resource-bundle> entry in the faces configuration, or <fmt:setBundle> for a JSP page — and the strings in a properties file per locale:

customerName=Customer name
customerNameHint=Enter the full legal name
placeOrder=Place order
orderReference=Order reference

Keep the keys named for what the text means rather than for what it currently says, so that rewording the caption does not require renaming the key.

Configuration

Property Default Description

labelAttributes

value, label, title, alt, itemLabel, headerText, footerText

Attributes a component library carries its rendered label in. Which ones apply varies by library, so extend the list for the one in use. Emptying the list makes the rule a no-op.

© 2026 Xygeni. All rights reserved