Last modified: August 22, 2025
The SearchInput component renders an input field that enables users to search. The component doesn’t provide search functionality out of the box, but includes props for managing input state and validation.
ui-extension-components-date-input
import React, { useState } from 'react';
import {
  Button,
  Flex,
  Form,
  SearchInput,
  Text,
  hubspot,
} from '@hubspot/ui-extensions';

hubspot.extend(({ actions }) => <Extension sendAlert={actions.addAlert} />);

const Extension = ({ sendAlert }) => {
  const [searchValue, setSearchValue] = useState('');

  const handleSubmit = (formData) => {
    const searchTerm = formData.targetValue.search;
    sendAlert({
      message: `You searched for: "${searchTerm}"`,
      type: 'success',
    });
  };

  return (
    <Form onSubmit={handleSubmit}>
      <Flex direction="column" gap="md">
        <SearchInput
          name="search"
          label="Search"
          placeholder="Enter your search term"
          value={searchValue}
          onChange={(value) => setSearchValue(value)}
        />
        <Button type="submit">Search</Button>
        {searchValue && <Text>Current search: {searchValue}</Text>}
      </Flex>
    </Form>
  );
};
PropTypeDescription
labelStringThe label text to display for the input.
nameStringThe unique identifier for the input.
valueStringThe value of the input.
placeholderStringText that appears in the input when it has no value set.
tooltipStringText that will appear in a tooltip on hover next to the input label.
requiredBooleanWhen set to true, displays a required field indicator.
readOnlyBooleanWhen set to true, the field is not editable.
descriptionStringInstructional message to help understand the purpose of the input.
errorBooleanWhen set to true, renders the error state and shows validationMessage as an error.
validationMessageStringThe text to show under the input for error or success validations. Will appear below the input. Learn more about validation messages.
getValidationMessage(value: string) => string | nullCalled to validate the input value and display a validation message. Depending on the width and length of message, the message display may appear above or inline with the input.
onChange(value: string) => voidA callback function that is invoked when the input value changes.
onInput(value: string) => voidA callback function that is invoked every time the field is edited by the user.
onBlur(value: string) => voidA function that is called when the field loses focus.
onFocus(value: string) => voidA function that is called when the field gets focused.
clearableBooleanWhen set to true, shows a clear button to clear the input. Default is true.

Validation messages

Using the validationMessage and getValidationMessage props, you can implement validation into the search input. By default, validationMessage will render as a green success message. When the error prop is true, the message will render as red and the search input will include a red border.
SearchInput validation messages and
errors
<>
  <SearchInput
    name="validation-message"
    placeholder="Validation message"
    validationMessage="This is a validation message"
  />
  <SearchInput
    name="validation-error"
    placeholder="Validation error"
    validationMessage="This is a validation error message"
    error
  />
</>

Table search example

The example below creates a searchable table.
Using a SearchInput component to search through table
data
import React, { useState } from 'react';
import {
  Button,
  Divider,
  Form,
  Heading,
  Table,
  TableHead,
  TableHeader,
  TableRow,
  TableBody,
  TableCell,
  Flex,
  SearchInput,
  hubspot,
} from '@hubspot/ui-extensions';

hubspot.extend(({ actions }) => <Extension sendAlert={actions.addAlert} />);

const Extension = ({ sendAlert }) => {
  const tableData = [
    { name: 'Mark Scout', role: 'Team Lead (MDR)' },
    { name: 'Dylan George', role: 'Macrodata Refiner' },
    { name: 'Irving Bailiff', role: 'Senior Refiner' },
    { name: 'Helly Riggs', role: 'New Hire' },
    { name: 'Burt Goodman', role: 'Department Head (O&D)' },
  ];

  const [filteredData, setFilteredData] = useState(tableData);

  const handleSubmit = (e) => {
    const searchTerm = e.targetValue.searchInput;
    sendAlert({ message: `You've searched for: ${searchTerm}` });
  };

  const searchTable = (e) => {
    const searchTerm = e.targetValue.searchInput;
    // Filter the table data based on search term
    const filtered = tableData.filter(
      (item) =>
        item.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
        item.role.toLowerCase().includes(searchTerm.toLowerCase())
    );

    setFilteredData(filtered);
    sendAlert({
      message: `Searched for: ${searchTerm}. Found ${filtered.length} result(s).`,
    });
  };

  return (
    <>
      <Form onSubmit={searchTable}>
        <Flex direction="column" gap="sm">
          <Heading>Searchable table</Heading>
          <Flex
            direction="row"
            gap="sm"
            alignSelf="end"
            align="end"
            justify="end"
          >
            <SearchInput name="searchInput" placeholder="Search Table" />
            <Button type="submit">Search</Button>
          </Flex>
<Table bordered={true} paginated={true} pageCount="5" limit={10}>
<TableHead>
<TableRow>
<TableHeader width="min">Name</TableHeader>
<TableHeader width="min">Role</TableHeader>
</TableRow>
</TableHead>
<TableBody>
              {filteredData.map((item, index) => (
<TableRow key={index}>
<TableCell width="min">{item.name}</TableCell>
<TableCell width="min">{item.role}</TableCell>
</TableRow>
              ))}
</TableBody>
</Table>
        </Flex>
      </Form>
    </>
  );
};