---
title: "Find and replace"
canonical_url: "https://www.nutrient.io/guides/document-authoring/editing-content/find-and-replace/"
md_url: "https://www.nutrient.io/guides/document-authoring/editing-content/find-and-replace.md"
last_updated: "2026-07-08T00:00:00.000Z"
description: "Search and replace text across a Document Authoring document with `searchText` and `replaceText`, using plain strings, regular expressions, or a callback."
---

# Find and replace text

Document Authoring can find and replace text from code inside a [transaction](https://www.nutrient.io/guides/document-authoring/editing-content/programmatic-editing.md). Use [`replaceText()`](https://www.nutrient.io/api/document-authoring/types/programmatic/textview/#replacetext) to replace every match and return the number of replacements. Use [`searchText()`](https://www.nutrient.io/api/document-authoring/types/programmatic/textview/#searchtext) to find the first match so you can act on it. Both methods accept a plain string or a regular expression.

Before you start, make sure the Document Authoring library is installed and running in your app. If you haven’t set it up yet, refer to the [getting started](https://www.nutrient.io/sdk/document-authoring/getting-started.md) guide.

The examples omit error handling. Add it before you use this code in production.

## Replace every match in the document

Call [`replaceText()`](https://www.nutrient.io/api/document-authoring/types/programmatic/textview/#replacetext) on the draft to replace text across the whole document. The method returns the number of replacements it made:

```js

const currentDoc = editor.currentDocument();

await currentDoc.transaction(async ({ draft }) => {
  const count = draft.replaceText('Acme Corp', 'Globex');

  console.log(`Replaced ${count} occurrences.`);

  return true;
});

```

## Match with a regular expression

Pass a `RegExp` to match a pattern. Use the global flag to replace every occurrence:

```js

await currentDoc.transaction(async ({ draft }) => {
  draft.replaceText(/\bTODO\b/g, 'DONE');

  return true;
});

```

## Change formatting while replacing

Pass a [`Replacement`](https://www.nutrient.io/api/document-authoring/types/programmatic/replacement/) object to change the text, its formatting, or both. To restyle matches without changing the text, set `formatting` only:

```js

await currentDoc.transaction(async ({ draft }) => {
  // Highlight every match and leave the text as-is.
  draft.replaceText(/confidential/gi, {
    formatting: { highlight: '#FEF08A', bold: true },

  });

  return true;
});

```

## Compute each replacement with a callback

Pass a function to build each replacement from the matched text. Use this pattern to reformat values such as dates, numbers, or IDs:

```js

await currentDoc.transaction(async ({ draft }) => {
  // Rewrite ISO dates (YYYY-MM-DD) as DD/MM/YYYY.
  draft.replaceText(/\d{4}-\d{2}-\d{2}/g, (match) => {
    const [year, month, day] = match.split('-');
    return `${day}/${month}/${year}`;
  });

  return true;
});

```

The callback returns either a string or a `Replacement` object.

## Find a single match

[`searchText()`](https://www.nutrient.io/api/document-authoring/types/programmatic/textview/#searchtext) returns the first match range, or `undefined` when it doesn’t find a match. Search a paragraph’s text view and use the range to update the match. This example highlights the matched text:

```js

await currentDoc.transaction(async ({ draft }) => {
  const paragraph = draft.body().content().addParagraph();
  const textView = paragraph.asTextView();

  textView.setText('Please review the highlighted clause before signing.');

  const match = textView.searchText('highlighted clause');

  if (match) {
    textView.setFormatting({ highlight: '#FEF08A' }, match.range);

  }

  return true;
});

```

To step through every match, pass the previous result range as the second argument to `searchText()` and continue until it returns `undefined`.

## Replace within a smaller scope

[`replaceText()`](https://www.nutrient.io/api/document-authoring/types/programmatic/textview/#replacetext) works at more than one level. Call it on the draft to update the whole document, or call it on a single paragraph’s text view to limit the change to that paragraph:

```js

await currentDoc.transaction(async ({ draft }) => {
  const [firstBlock] = draft.body().content().blocklevels();

  if (firstBlock?.type === 'paragraph') {
    firstBlock.asTextView().replaceText('draft', 'final');
  }

  return true;
});

```

## Learn more

**[Programmatic editing](https://www.nutrient.io/guides/document-authoring/editing-content/programmatic-editing.md)**\
Learn how transactions work and how to use the document model.

**[DocJSON](https://www.nutrient.io/guides/document-authoring/working-with-documents/docjson.md)**\
Load and save Document Authoring’s native format.
---

## Related pages

- [Use copy/paste and HTML interoperability](/guides/document-authoring/editing-content/copy-paste-and-html-interoperability.md)
- [Work with lists](/guides/document-authoring/editing-content/lists.md)
- [Work with footnotes and endnotes](/guides/document-authoring/editing-content/footnotes-and-endnotes.md)
- [Edit documents programmatically](/guides/document-authoring/editing-content/programmatic-editing.md)
- [Work with images and shapes](/guides/document-authoring/editing-content/images-and-shapes.md)
- [Format text](/guides/document-authoring/editing-content/text-and-formatting.md)
- [Work with tables](/guides/document-authoring/editing-content/tables.md)

