This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/web/headless/color-presets.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Headless color presets | Nutrient Web SDK

Every annotation namespace that has color exposes a getColorPresets() method. The returned list mirrors the swatches the default toolbar would render, including any overrides from the customer’s annotationToolbarColorPresets configuration callback. Build one color picker component, point it at any namespace, and your picker stays in sync with however the customer customizes the SDK.

Looking for the visual side of this? See the tools.contextual slot for replacing the inline color picker that appears in the annotation property toolbar. This page covers the programmatic surface you’ll call from inside that custom UI.

When to use this

Reach for the headless color preset API when you’re building:

  • A custom color picker that mirrors the default SDK swatches.
  • A per-tool color palette that switches its source as the active tool changes.
  • A design system color picker that needs to respect the customer’s preset configuration without reimplementing the resolution logic.
  • A test or storybook entry that needs to enumerate the swatches the SDK currently uses.

API reference

Call getColorPresets() on the namespace whose presets you want to read.

NamespaceReturns presets for
instance.annotations.textMarkup.getColorPresets()Highlight, underline, strikeout, and squiggly colors.
instance.annotations.shape.getColorPresets()Rectangle, ellipse, line, polyline, and polygon stroke and fill.
instance.annotations.link.getColorPresets()Link annotation border color.
instance.annotations.redaction.getColorPresets()Redaction fill, outline, and overlay text colors.
instance.annotations.measurement.getColorPresets()Measurement annotation stroke color.
instance.annotations.text.getColorPresets()Text annotation font, background, and border colors.

The shape of the returned object varies by namespace. Most follow the same pattern: an object keyed by the property being colored, with each entry holding a presets array of ColorPreset values, plus a showColorPicker Boolean.

Per-namespace shapes:

  • text-markup — Grouped by highlight and markup.
  • text — Grouped by fontColor, backgroundColor, and borderColor.
  • redaction — Grouped by fillColor, outlineColor, and overlayTextColor.
  • shape, link, and measurement — Same per-property pattern, with one or two color groups each.

A ColorPreset has two fields: a required color (a NutrientViewer.Color) and an optional localization string. The default UI uses localization for tooltips and aria-labels. Surface it in your own pickers if you want the swatches to be accessible and localized.

Example: A highlight color picker

Render the swatches the default markup toolbar would show for the highlight tool, and apply the chosen color to the current annotation preset:

const instance = await NutrientViewer.load({
container: "#viewer",
document: "contract.pdf"
});
const presets = instance.annotations.textMarkup.getColorPresets();
const palette = document.getElementById("highlight-palette");
presets.highlight.presets.forEach((preset) => {
const swatch = document.createElement("button");
swatch.className = "color-swatch";
swatch.style.backgroundColor = preset.color.toHex();
// `localization` is a translation key, pipe it through your i18n layer
// if you have one, or fall back to a sensible default.
if (preset.localization) {
swatch.title = preset.localization;
swatch.setAttribute("aria-label", preset.localization);
}
swatch.onclick = () => {
// Update the preset value, then activate it. `setCurrentAnnotationPreset`
// only switches which preset is active, it does not accept a value patch.
instance.setAnnotationPresets((presets) => ({
...presets,
highlight: { ...presets.highlight, color: preset.color }
}));
instance.setCurrentAnnotationPreset("highlight");
};
palette.appendChild(swatch);
});

How preset resolution works

The values returned by getColorPresets() are the resolved ones; they reflect both the SDK defaults and any overrides from the customer’s annotationToolbarColorPresets callback. You don’t need to rerun the resolution logic in your own code: A custom picker built on getColorPresets() picks up customer overrides automatically.