Stable Template IDs in JavaScript: Avoiding Configuration Bugs

Template selection seems simple: show a list of layouts, let a user choose one, and save the selection.
But what happens when the list changes?
If an application stores a template's position instead of its identity, adding a new template or reordering existing ones can cause saved configurations to point to the wrong layout. This becomes especially problematic in applications where users expect their saved designs to remain consistent over time.
Let's explore a more reliable approach.
The problem with array indexes
Consider a basic template list:
const templates = [
{ id: "classic", name: "Classic" },
{ id: "modern", name: "Modern" },
{ id: "compact", name: "Compact" },
];
Imagine saving the selected template using its array index:
const selectedTemplate = 1;
At first, index 1 represents the Modern template.
Now suppose a developer inserts a new template at the beginning of the array:
const templates = [
{ id: "minimal", name: "Minimal" },
{ id: "classic", name: "Classic" },
{ id: "modern", name: "Modern" },
{ id: "compact", name: "Compact" },
];
The saved index 1 now refers to Classic instead of Modern.
The saved configuration hasn't changed, but its meaning has. This is a subtle bug that can affect any application that persists positional identifiers.
Store a stable identifier instead
A more reliable approach is to save a template ID:
const selectedTemplateId = "modern";
The application can resolve the selected template when it needs to render the corresponding layout:
function findTemplate(templates, templateId) {
return templates.find(
(template) => template.id === templateId
);
}
This approach allows templates to be reordered without changing the identity of a saved selection.
The important requirement is that IDs remain stable and unique. Renaming a display label should not require changing the underlying ID.
Handle missing templates explicitly
Stable IDs solve the reordering problem, but they do not eliminate every edge case.
A template might be removed, renamed internally, or become unavailable in a newer application version.
A lookup can therefore return undefined. The application should decide what happens next rather than assuming every saved ID will always exist.
For example:
function resolveTemplate(templates, templateId) {
const selected = findTemplate(templates, templateId);
if (selected) {
return selected;
}
return templates.find(
(template) => template.id === "classic"
) ?? templates[0] ?? null;
}
This example uses a fallback strategy. In a production application, the fallback should be an intentional product decision, and the interface may need to inform the user when a saved template is no longer available.
Keep the selected ID in persisted settings
A saved template choice should be part of the configuration it belongs to.
For example, a bundle design might store its selected template in a settings object:
const designSettings = {
template: "modern",
};
The application can then restore the selection when the user reopens the editor.
In Cruxtab Bundle Builder & BYOB, the selected template ID is stored in BundleDesign.settings.template when the bundle is saved.
Keeping the selection with the design configuration gives the application a defined place to retrieve the user's choice.
Test template changes, not just template selection
A useful test suite should cover more than selecting an option.
Consider these scenarios:
- Selecting a template and saving it.
- Reopening a saved configuration.
- Reordering templates without changing their IDs.
- Renaming a display label while retaining its ID.
- Loading a configuration with an unknown template ID.
- Handling an empty template list.
These tests help detect problems that may not appear during ordinary development but can emerge as an application evolves.
Conclusion
A template picker is a small interface backed by an important data-modeling decision.
Using stable identifiers instead of array indexes helps protect saved configurations from changes in ordering. Explicit fallback behavior and lifecycle tests provide additional protection when templates evolve.
The same principles apply to page builders, email editors, dashboard layouts, form builders, and any application that allows users to select and save predefined configurations.
The takeaway: persist the identity of the user's choice, not its temporary position in a list.
Comments
Join the discussionNo comments yet. Be the first to comment.




