> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-audit-mechanical-fixes.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Text Formatter

> Extend the CometChatTextFormatter base class to implement custom inline text patterns with regex and callbacks in Angular.

<Accordion title="AI Integration Quick Reference">
  | Field          | Value                                                                                                                                                                                      |
  | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
  | Package        | `@cometchat/chat-uikit-angular`                                                                                                                                                            |
  | Key class      | `CometChatTextFormatter` (abstract base class for custom formatters)                                                                                                                       |
  | Required setup | `CometChatUIKit.init(uiKitSettings)` then `CometChatUIKit.login("UID")`                                                                                                                    |
  | Purpose        | Extend to create custom inline text patterns with regex, styling, and callbacks                                                                                                            |
  | Features       | Text formatting, customizable styles, dynamic text replacement, input field integration, key event callbacks                                                                               |
  | Related        | [ShortCut Formatter](/ui-kit/angular/guides/shortcut-formatter) \| [Mentions Formatter](/ui-kit/angular/guides/mentions-formatter) \| [All Guides](/ui-kit/angular/guides/guides-overview) |
</Accordion>

`CometChatTextFormatter` is an abstract class for formatting text in the message composer and message bubbles. Extend it to build custom formatters — hashtags, keywords, or any regex-based pattern.

| Capability          | Description                                         |
| ------------------- | --------------------------------------------------- |
| Text formatting     | Auto-format text based on regex patterns and styles |
| Custom styles       | Set colors, fonts, and backgrounds for matched text |
| Dynamic replacement | Regex-based find-and-replace in user input          |
| Input integration   | Real-time monitoring of the composer input field    |
| Key event callbacks | Hooks for `keyUp` and `keyDown` events              |

<Warning>
  Always wrap formatted output in a `<span>` with a unique CSS class (e.g. `"custom-hashtag"`). This tells the UI Kit to render it as-is instead of sanitizing it.
</Warning>

***

## Steps

### 1. Import the base class

```typescript theme={null}
import { CometChatTextFormatter } from "@cometchat/chat-uikit-angular";
```

### 2. Extend it

```typescript theme={null}
class HashTagTextFormatter extends CometChatTextFormatter {
  readonly id = "hashtag-formatter";
  override priority = 15;

  getRegex(): RegExp {
    return /\B#(\w+)\b/g;
  }

  format(text: string): string {
    // Apply formatting logic
    return text;
  }
}
```

### 3. Implement the regex pattern

Return the regex that matches your target pattern from `getRegex()`:

```typescript theme={null}
getRegex(): RegExp {
  return /\B#(\w+)\b/g;
}
```

### 4. Implement the format method

The `format()` method receives the raw text and returns formatted HTML:

```typescript theme={null}
format(text: string): string {
  if (!text) {
    this.originalText = "";
    this.formattedText = "";
    return "";
  }

  this.originalText = text;
  this.formattedText = text.replace(
    this.getRegex(),
    '<span class="custom-hashtag" style="color: #30b3ff;">#$1</span>'
  );
  return this.formattedText;
}
```

### 5. Optionally implement shouldFormat

Control when the formatter is applied:

```typescript theme={null}
shouldFormat(text: string, message?: CometChat.BaseMessage): boolean {
  return this.getRegex().test(text);
}
```

***

## Example

A hashtag formatter used with `cometchat-message-list` and `cometchat-message-composer`.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-audit-mechanical-fixes/0Dzaagp0tKHyO4xb/images/53d9b07c-custom_hashtag_formatter_web_screens-c7f853c807e9f2fa63e0e1f6245e0a27.png?fit=max&auto=format&n=0Dzaagp0tKHyO4xb&q=85&s=41f4aa12650e752cce2ba45590e3bd6b" width="1282" height="802" data-path="images/53d9b07c-custom_hashtag_formatter_web_screens-c7f853c807e9f2fa63e0e1f6245e0a27.png" />
</Frame>

<Tabs>
  <Tab title="HashTagTextFormatter.ts">
    ```typescript expandable theme={null}
    import { CometChatTextFormatter } from "@cometchat/chat-uikit-angular";

    export class HashTagTextFormatter extends CometChatTextFormatter {
      readonly id = "hashtag-text-formatter";
      override priority = 15;

      private hashtags: string[] = [];

      getRegex(): RegExp {
        return /\B#(\w+)\b/g;
      }

      format(text: string): string {
        if (!text) {
          this.originalText = "";
          this.formattedText = "";
          this.hashtags = [];
          this.metadata = { hashtags: this.hashtags };
          return "";
        }

        this.originalText = text;
        this.hashtags = [];

        this.formattedText = text.replace(this.getRegex(), (match, tag) => {
          this.hashtags.push(`#${tag}`);
          return `<span class="custom-hashtag" style="color: #5dff05;">#${tag}</span>`;
        });

        this.metadata = { hashtags: this.hashtags };
        return this.formattedText;
      }

      getHashtags(): string[] {
        return [...this.hashtags];
      }

      override reset(): void {
        super.reset();
        this.hashtags = [];
      }
    }
    ```
  </Tab>

  <Tab title="Component Usage">
    Pass the formatter via the `textFormatters` input on the message list and composer.

    ```typescript expandable theme={null}
    import { Component, OnInit } from "@angular/core";
    import { CometChat } from "@cometchat/chat-sdk-javascript";
    import { CometChatMessageListComponent, CometChatMessageComposerComponent } from "@cometchat/chat-uikit-angular";
    import { HashTagTextFormatter } from "./HashTagTextFormatter";

    @Component({
      selector: "app-message-demo",
      standalone: true,
      imports: [CometChatMessageListComponent, CometChatMessageComposerComponent],
      template: `
        <cometchat-message-list
          [user]="chatUser"
          [textFormatters]="textFormatters">
        </cometchat-message-list>
        <cometchat-message-composer
          [user]="chatUser"
          [textFormatters]="textFormatters">
        </cometchat-message-composer>
      `,
    })
    export class MessageDemoComponent implements OnInit {
      chatUser: CometChat.User | undefined;
      textFormatters = [new HashTagTextFormatter()];

      ngOnInit() {
        CometChat.getUser("uid").then((user) => {
          this.chatUser = user;
        });
      }
    }
    ```
  </Tab>
</Tabs>

***

## Methods Reference

| Field                          | Type                       | Description                                                                  |
| ------------------------------ | -------------------------- | ---------------------------------------------------------------------------- |
| `id`                           | `abstract readonly string` | Unique identifier for the formatter instance                                 |
| `priority`                     | `number`                   | Execution order in the pipeline (lower = earlier, default 100)               |
| `getRegex()`                   | `abstract method`          | Returns the regex pattern for detecting formattable content                  |
| `format(text)`                 | `abstract method`          | Applies formatting transformations and returns formatted text                |
| `getFormattedText()`           | `method`                   | Returns the stored formatted text after `format()` is called                 |
| `getOriginalText()`            | `method`                   | Returns the original text before formatting                                  |
| `getMetadata()`                | `method`                   | Returns metadata extracted during formatting                                 |
| `reset()`                      | `method`                   | Clears original text, formatted text, and metadata                           |
| `shouldFormat(text, message?)` | `method`                   | Returns whether this formatter should process the given text (default: true) |

<Warning>
  Formatters are applied in priority order (lower priority number = earlier in pipeline). The built-in URL formatter uses priority 10, mentions uses 20. Choose your custom formatter's priority accordingly.
</Warning>

***

## Override Methods

<Tabs>
  <Tab title="format">
    The core method that applies formatting. Store original text, apply transformations, store metadata, and return the result.

    ```typescript theme={null}
    format(text: string): string {
      if (!text) {
        this.originalText = "";
        this.formattedText = "";
        return "";
      }
      this.originalText = text;
      this.formattedText = this.customLogicToFormatText(text);
      return this.formattedText;
    }
    ```
  </Tab>

  <Tab title="getRegex">
    Returns the regex pattern used to detect formattable content.

    ```typescript theme={null}
    getRegex(): RegExp {
      return /\B#(\w+)\b/g;
    }
    ```
  </Tab>

  <Tab title="shouldFormat">
    Optionally override to conditionally skip formatting.

    ```typescript theme={null}
    shouldFormat(text: string, message?: CometChat.BaseMessage): boolean {
      // Only format text messages
      return message?.getType() === 'text';
    }
    ```
  </Tab>

  <Tab title="reset">
    Override to clear custom state alongside the base state.

    ```typescript expandable theme={null}
    override reset(): void {
      super.reset();
      // Clear any custom state
      this.customData = [];
    }
    ```
  </Tab>
</Tabs>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Mentions Formatter" href="/ui-kit/angular/guides/mentions-formatter">
    Add @mentions with styled tokens.
  </Card>

  <Card title="Message Composer" href="/ui-kit/angular/components/cometchat-message-composer">
    Customize the message input component.
  </Card>

  <Card title="All Guides" href="/ui-kit/angular/guides/guides-overview">
    Browse all feature and formatter guides.
  </Card>

  <Card title="ShortCut Formatter" href="/ui-kit/angular/guides/shortcut-formatter">
    Implement text expansion shortcuts.
  </Card>
</CardGroup>
