- How do I integrate loupe/matcher with Laravel Scout for search result snippets?
- Use Scout’s `toSearchableArray()` to fetch raw text, then pass it to `Formatter::format()` with your query. Cache the results with Laravel’s cache system to avoid reprocessing. For example, extend Scout’s `Searchable` trait to include snippet generation in your model’s search output.
- Will this work with Laravel 10+? Are there breaking changes between versions?
- The package targets PHP 8.1+ and Laravel 9+. Check the GitHub releases for version-specific notes, but pin to a minor version (e.g., `^0.2.4`) to avoid instability until 1.0. The API is still evolving, so monitor the changelog for deprecations.
- Can I customize the HTML tags used for highlighting (e.g., `<mark>` vs. `<span>`)?
- Yes, configure the `Formatter` with `FormatterOptions` to set custom tags. For Blade/Livewire, use `<mark>` for native browser styling or `<em>` for semantic emphasis. Example: `$options->withHighlightTag('mark')->withHighlightClass('bg-yellow-200')`.
- How does performance scale with large result sets (e.g., 10,000+ documents)?
- Tokenization and matching can be slow for large datasets. Mitigate this by caching matches per query/document ID (e.g., `Cache::remember()`) and pre-calculating snippets for frequent searches. For extreme cases, fall back to regex-based highlighting or client-side processing.
- Does loupe/matcher support multilingual search (e.g., German, Arabic)?
- Yes, it includes locale-specific tokenizers (e.g., German for umlauts/ß, English for decomposition). For RTL languages like Arabic, ensure your `FormatterOptions` account for text direction in cropping. The `ext-intl` extension is required for full locale support.
- How do I handle negated queries (e.g., `-exclude`) in my Laravel search form?
- Pass the raw user query to the `Tokenizer` (e.g., `tokenizer->tokenize($request->query)`). The library automatically processes negations and phrases. For Scout, ensure your search backend supports these operators or pre-process the query before indexing.
- Can I use this with database full-text search (e.g., MySQL `MATCH...AGAINST`)?
- Yes, fetch raw text from your database results, then pass it to `Formatter::format()`. For performance, cache the formatted snippets. If using Laravel’s query builder, extend it to include snippet generation alongside full-text search clauses.
- What’s the best way to register loupe/matcher as a Laravel service?
- Bind the `Tokenizer`, `Matcher`, and `Formatter` in a service provider (e.g., `LoupeMatcherServiceProvider`). Use dependency injection in controllers or create a facade (e.g., `Matcher::highlight($text, $query)`) for cleaner Blade/Livewire usage.
- Are there alternatives if I need simpler highlighting without advanced features?
- For basic highlighting, consider `str_ireplace()` or regex-based solutions. For more features, explore `spatie/laravel-searchable` (simpler) or `algolia/algoliasearch-php` (enterprise). Loupe/matcher excels with phrases, negations, and multilingual support.
- How do I test this in a CI pipeline? What edge cases should I cover?
- Test with mixed-case queries, special characters, and locale-specific terms (e.g., German umlauts). Verify caching behavior and edge cases like empty queries or no matches. Use PHPUnit to mock the `Tokenizer` and `Matcher` for unit tests.