Framework-agnostic text highlighting using CSS Custom Highlight API.
npm install react-css-highlightimport { createHighlight } from 'react-css-highlight/vanilla';
import 'react-css-highlight/styles';
const controller = createHighlight(document.getElementById('content'), {
search: 'JavaScript',
onHighlightChange: (count) => console.log(`${count} matches`)
});Note: This package requires a bundler (Vite, Webpack, Esbuild, etc.) or module system (Node.js, ES modules). It does not work with plain
<script>tags. If you need a no-build solution, see the Full Documentation for alternatives.
Creates a highlight controller for managing text highlights.
Returns: HighlightController
interface HighlightController {
readonly matchCount: number;
update(options: Partial<HighlightOptions>): void;
refresh(): void;
destroy(): void;
}interface HighlightOptions {
search: string | string[]; // Required
highlightName?: string; // Default: "highlight"
caseSensitive?: boolean; // Default: false
wholeWord?: boolean; // Default: false
maxHighlights?: number; // Default: 1000
ignoredTags?: string[]; // Default: []
onHighlightChange?: (count: number) => void;
onError?: (error: Error) => void;
}<script setup>
import { ref, onMounted, watch } from 'vue';
import { createHighlight } from 'react-css-highlight/vanilla';
const searchTerm = ref('');
const contentRef = ref(null);
let controller = null;
onMounted(() => {
controller = createHighlight(contentRef.value, {
search: searchTerm.value
});
});
watch(searchTerm, (term) => controller?.update({ search: term }));
</script>
<template>
<input v-model="searchTerm">
<div ref="contentRef">Content here</div>
</template><script>
import { onMount } from 'svelte';
import { createHighlight } from 'react-css-highlight/vanilla';
let searchTerm = '';
let element;
let controller;
onMount(() => {
controller = createHighlight(element, { search: searchTerm });
});
$: controller?.update({ search: searchTerm });
</script>
<input bind:value={searchTerm}>
<div bind:this={element}>Content here</div>const input = document.getElementById('search');
const content = document.getElementById('content');
const controller = createHighlight(content, {
search: '',
onHighlightChange: (count) => {
document.getElementById('count').textContent = count;
}
});
input.addEventListener('input', (e) => {
controller.update({ search: e.target.value });
});For virtualized lists or dynamically changing content, use refresh():
const content = document.getElementById('virtualList');
const controller = createHighlight(content, {
search: 'keyword'
});
// After DOM changes (virtualization, infinite scroll, etc.)
virtualList.addEventListener('scroll', () => {
// DOM has changed, re-highlight
controller.refresh();
});
// Or after programmatic content updates
function updateContent(newItems) {
renderItems(newItems);
controller.refresh(); // Re-highlight new DOM
}import {
isHighlightAPISupported, // Check browser support
findTextMatches, // Find matches in DOM
registerHighlight, // Register with CSS.highlights
removeHighlight, // Remove from CSS.highlights
normalizeSearchTerms, // Normalize search input
DEFAULT_MAX_HIGHLIGHTS,
IGNORED_TAG_NAMES
} from 'react-css-highlight/vanilla';- Chrome 105+
- Edge 105+
- Safari 17.2+
- Firefox 140+
Check support at runtime:
import { isHighlightAPISupported } from 'react-css-highlight/vanilla';
if (!isHighlightAPISupported()) {
console.warn('CSS Custom Highlight API not supported');
}
`Low-level utilities for advanced use cases:
```javascript
import {
isHighlightAPISupported, // Check browser support
findTextMatches, // Find matches in DOM
registerHighlight, // Register with CSS.highlights
removeHighlight, // Remove from CSS.highlights
normalizeSearchTerms, // Normalize search input
DEFAULT_MAX_HIGHLIGHTS, // Default: 1000
IGNORED_TAG_NAMES, // Default ignored HTML tags
} from 'react-css-highlight/vanilla';
// Type exports for advanced usage
import type {
HighlightMatch, // Match result type (used with findTextMatches)
HighlightOptions, // Controller options type
HighlightController // Controller interface
} from 'react-css-highlight/vanilla';Note: Most users don't need these utilities directly. Use
createHighlight()for the recommended high-level API. These are exported for framework integrations and advanced customization.