- How do I set up Spatie’s Laravel site search for a blog with 10K+ pages?
- Start with SQLite FTS5 for simplicity: install the package, configure `config/site-search.php` to exclude non-content routes (e.g., admin), then run `php artisan site-search:crawl --sync` for testing. For large indexes, switch to Meilisearch—it handles scale better but requires external hosting. Monitor crawl jobs via Laravel queues and consider chunking URLs to avoid timeouts.
- Can I customize what gets indexed (e.g., exclude API routes or prioritize H1 tags)?
- Yes. Extend the `SearchProfile` and `Indexer` interfaces to filter routes or modify indexed content. For example, override `shouldCrawl()` to exclude `/api/*` or use `extractContent()` to prioritize `<h1>` tags. The package’s modular design makes this straightforward without core modifications.
- What Laravel versions and PHP requirements does this package support?
- The package supports Laravel 10+ and PHP 8.1+. For Laravel 12+, it leverages modern features like enums and attributes. PHP 8.4+ is recommended for full compatibility with Meilisearch’s advanced features. Always check the [latest docs](https://spatie.be/docs/laravel-site-search) for version-specific notes.
- How do I handle dynamic content (e.g., SPAs or JavaScript-rendered pages)?
- By default, the crawler fetches static HTML. For SPAs (React, Vue), use a custom `Indexer` to render pages server-side (e.g., via Laravel’s `route()` method) or integrate with your headless CMS API. Avoid relying on client-side JavaScript—pre-render critical content or use a hybrid approach with API endpoints.
- Is Meilisearch required, or can I use SQLite/MySQL for production?
- SQLite FTS5 is the default and works well for small-to-medium sites (e.g., <50K pages). For larger scales or advanced features (typo tolerance, synonyms), use Meilisearch. SQLite is simpler to deploy but may slow down with frequent updates. Meilisearch requires external setup but offloads indexing workloads.
- How do I schedule regular crawls (e.g., daily updates) without blocking requests?
- Use Laravel’s scheduler in `app/Console/Kernel.php` to run `php artisan site-search:crawl` daily. The crawler runs asynchronously via queues (database/Redis), so it won’t block HTTP requests. For large sites, limit concurrency in `config/site-search.php` to avoid server strain. Monitor queue jobs with Horizon or `php artisan queue:work --sleep=3 --tries=3`.
- What’s the best way to debug crawl failures (e.g., 404s or timeouts)?
- Run crawls in sync mode for debugging: `php artisan site-search:crawl --sync`. Check logs in `storage/logs/laravel-site-search.log` for errors. Use the `SearchProfile::configureCrawler()` method to adjust timeouts, retries, or user-agent headers. For persistent issues, implement a custom `Crawler` class to log failed URLs to a database table.
- Can I integrate search results into a Vue/React frontend without Blade?
- Yes. Expose search via an API endpoint (e.g., `Route::get('/search', [SearchController::class, 'index'])`) that returns JSON. Use the `SiteSearch` facade to query the index. For SPAs, cache results client-side or implement server-side rendering for critical search pages. The package’s query builder supports faceting and filtering for complex UIs.
- How do I migrate from SQLite to Meilisearch without downtime?
- First, crawl your site into SQLite as usual. Then, install Meilisearch, update `config/site-search.php` to use the `meilisearch` driver, and re-index with `php artisan site-search:create-index --driver=meilisearch`. Use a database driver like PostgreSQL for a temporary hybrid setup if needed. Test queries thoroughly before switching fully.
- Are there alternatives to Spatie’s package for Laravel site search?
- For simple use cases, consider Laravel Scout with Algolia or Meilisearch (paid). For open-source alternatives, check `laravel-searchable` (basic) or `knuckleswtf/searchable` (attribute-based). Spatie’s package stands out for its crawling flexibility, async design, and no-dependency default (SQLite). If you need real-time search, pair it with Laravel Echo or a dedicated search API.