{"id":24555991,"url":"https://github.com/mezcalito/ux-search","last_synced_at":"2026-01-17T00:03:17.707Z","repository":{"id":273703315,"uuid":"896077504","full_name":"Mezcalito/ux-search","owner":"Mezcalito","description":"Effortless search and faceted search with Symfony UX and Mezcalito UX Search","archived":false,"fork":false,"pushed_at":"2026-01-15T18:08:02.000Z","size":833,"stargazers_count":62,"open_issues_count":6,"forks_count":5,"subscribers_count":5,"default_branch":"0.x","last_synced_at":"2026-01-15T20:47:54.059Z","etag":null,"topics":["algolia","faceted-search","meilisearch","search","symfony","symfony-bundle","symfony-ux"],"latest_commit_sha":null,"homepage":"https://ux-search.mezcalito.dev","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Mezcalito.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-11-29T13:53:55.000Z","updated_at":"2026-01-15T18:07:14.000Z","dependencies_parsed_at":"2025-03-16T17:46:01.048Z","dependency_job_id":"dcf33c32-1946-4795-a995-83651bc8df94","html_url":"https://github.com/Mezcalito/ux-search","commit_stats":null,"previous_names":["mezcalito/ux-search"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/Mezcalito/ux-search","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mezcalito%2Fux-search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mezcalito%2Fux-search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mezcalito%2Fux-search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mezcalito%2Fux-search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mezcalito","download_url":"https://codeload.github.com/Mezcalito/ux-search/tar.gz/refs/heads/0.x","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mezcalito%2Fux-search/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28489794,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T23:55:29.509Z","status":"ssl_error","status_checked_at":"2026-01-16T23:55:29.108Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algolia","faceted-search","meilisearch","search","symfony","symfony-bundle","symfony-ux"],"created_at":"2025-01-23T04:36:07.358Z","updated_at":"2026-01-17T00:03:17.695Z","avatar_url":"https://github.com/Mezcalito.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mezcalito UX Search\n\n[![Latest Version](https://img.shields.io/packagist/v/mezcalito/ux-search.svg)](https://packagist.org/packages/mezcalito/ux-search)\n[![License](https://img.shields.io/packagist/l/mezcalito/ux-search.svg)](https://github.com/mezcalito/ux-search/blob/main/LICENSE)\n[![PHP Version](https://img.shields.io/packagist/php-v/mezcalito/ux-search.svg)](https://packagist.org/packages/mezcalito/ux-search)\n\nA powerful, flexible, and easy-to-use search and faceted search system for Symfony applications, built with Twig Components and Live Components.\n\n[![Effortless search and faceted search with Symfony UX and Mezcalito UX Search](docs/image/preview.png)](https://ux-search.mezcalito.dev/)\n\n**[View Live Demo](https://ux-search.mezcalito.dev/demo)** | **[Documentation](docs/)** | **[Report Issues](https://github.com/mezcalito/ux-search/issues)**\n\n---\n\n## Why Use This Bundle?\n\n- **🚀 Quick Setup**: Get a working search in minutes with the maker command\n- **🔌 Multiple Adapters**: Support for Algolia, Meilisearch, and Doctrine ORM\n- **🎨 Fully Customizable**: Override templates and components to match your design\n- **⚡ Live Updates**: Built with Symfony UX Live Components for reactive UI\n- **🎯 Faceted Search**: Rich filtering with refinement lists, range sliders, and more\n- **📦 Production Ready**: Used in production with comprehensive test coverage\n\n## Features\n\n- **Multiple Search Configurations**: Create and manage multiple searches, each with its own unique configuration\n- **Flexible Adapters**:\n  - **Algolia**: Cloud-based search with advanced features\n  - **Meilisearch**: Self-hosted open-source search engine\n  - **Doctrine ORM**: Use your existing database for small datasets\n- **Rich UI Components**: Pre-built components for search input, facets, pagination, sorting, and more\n- **Faceted Navigation**: Multiple facet types (refinement lists, range inputs, range sliders)\n- **Live Components**: Real-time updates without page reloads\n- **Event System**: Customize search behavior with pre/post search events\n- **SEO Friendly**: URL rewriting support for search parameters\n- **Customizable**: Override any template or extend any component\n\n## Requirements\n\n- PHP 8.3 or higher\n- Symfony 6.4+ or 7.0+ or 8.0+\n- Symfony UX (Live Components, Twig Components)\n\n\n## Installation\n\nInstall the bundle via Composer:\n\n```bash\ncomposer require mezcalito/ux-search\n```\n\nIf you're **not** using Symfony Flex, you'll need to manually register the bundle in `config/bundles.php`:\n\n```php\n// config/bundles.php\nreturn [\n    // ...\n    Mezcalito\\UxSearchBundle\\MezcalitoUxSearchBundle::class =\u003e ['all' =\u003e true],\n];\n```\n\n## Quick Start\n\n### 1. Configure an Adapter\n\nCreate a configuration file `config/packages/mezcalito_ux_search.yaml`:\n\n```yaml\nmezcalito_ux_search:\n    default_adapter: 'default'\n    adapters:\n        default: '%env(MEZCALITO_UX_SEARCH_DEFAULT_DSN)%'\n```\n\nAdd the DSN to your `.env` file (choose one):\n\n```bash\n# For Algolia\nMEZCALITO_UX_SEARCH_DEFAULT_DSN=algolia://YOUR_API_KEY@YOUR_APP_ID\n\n# For Meilisearch\nMEZCALITO_UX_SEARCH_DEFAULT_DSN=meilisearch://YOUR_MASTER_KEY@localhost:7700\n\n# For Doctrine ORM\nMEZCALITO_UX_SEARCH_DEFAULT_DSN=doctrine://default\n```\n\n### 2. Create Your First Search\n\nUse the maker command to generate a search class:\n\n```bash\nphp bin/console make:search\n```\n\nThe command will ask you for:\n- **Index name**: For Algolia/Meilisearch, the index name. For Doctrine, the entity FQCN (e.g., `App\\Entity\\Product`)\n- **Search name** (optional): Custom name for your search (defaults to class name without \"Search\" suffix)\n- **Adapter** (optional): Which adapter to use (defaults to `default_adapter`)\n\nThis creates a search class in `src/Search/` that you can customize.\n\n### 3. Render the Search in Your Template\n\nIn any Twig template:\n\n```twig\n{# Using Twig component syntax #}\n\u003ctwig:Mezcalito:UxSearch:Layout name=\"product\"/\u003e\n\n{# Or using component function #}\n{{ component('Mezcalito:UxSearch:Layout', { name: 'product' }) }}\n```\n\nThat's it! You now have a working search with facets, pagination, and live updates. 🎉\n\n## Choosing an Adapter\n\nThree adapters are available, each with different strengths:\n\n| Adapter         | Best For                    | Performance | Cost    | Setup Complexity |\n|-----------------|-----------------------------|-------------|---------|------------------|\n| **Algolia**     | Production, large datasets  | ⭐⭐⭐         | 💰 Paid | Easy             |\n| **Meilisearch** | Self-hosted production      | ⭐⭐⭐         | 🆓 Free | Medium           |\n| **Doctrine**    | Development, small datasets | ⭐⭐          | 🆓 Free | Very Easy        |\n\n### Adapter DSN Format\n\n| Adapter     | DSN Format                     | Documentation                          |\n|-------------|--------------------------------|----------------------------------------|\n| Algolia     | `algolia://apiKey@appId`       | [View docs](docs/usage/algolia.md)     |\n| Meilisearch | `meilisearch://key@host:port`  | [View docs](docs/usage/meilisearch.md) |\n| Doctrine    | `doctrine://entityManagerName` | [View docs](docs/usage/doctrine.md)    |\n\n**Need another provider?** You can [create your own adapter](docs/create-own-adapter.md).\n\n## Customizing Your Search\n\n### Adding Facets, Sorting, and More\n\nOnce you've created a search class, customize it by editing the `build()` method:\n\n```php\nuse Mezcalito\\UxSearchBundle\\Search\\AbstractSearch;\nuse Mezcalito\\UxSearchBundle\\Attribute\\AsSearch;\nuse Mezcalito\\UxSearchBundle\\Twig\\Components\\Facet\\RangeInput;\n\n#[AsSearch(index: 'products', adapter: 'default')]\nclass ProductSearch extends AbstractSearch\n{\n    public function build(array $options = []): void\n    {\n        // Add facets for filtering\n        $this-\u003eaddFacet('brand', 'Brand');\n        $this-\u003eaddFacet('category', 'Category');\n        $this-\u003eaddFacet('price', 'Price', RangeInput::class);\n\n        // Add sorting options\n        $this-\u003eaddAvailableSort('name', 'Name');\n        $this-\u003eaddAvailableSort('price', 'Price');\n        $this-\u003eaddAvailableSort('created_at', 'Newest');\n\n        // Configure pagination\n        $this-\u003esetAvailableHitsPerPage([12, 24, 48]);\n\n        // Adapter-specific parameters\n        $this-\u003esetAdapterParameters([\n            // Adapter-specific options here\n        ]);\n    }\n}\n```\n\n📖 **[Full customization guide](docs/usage/customize-your-search.md)**\n\n\n### Customizing the UI\n\nThe bundle provides a complete set of UI components that you can use individually or override:\n\n#### Core Components\n\n| Component       | Description                                             | Documentation                          |\n|-----------------|---------------------------------------------------------|----------------------------------------|\n| **Layout**      | Root wrapper component containing all search elements   | [Docs](docs/components/Layout.md)      |\n| **SearchInput** | Text search input with live updates                     | [Docs](docs/components/SearchInput.md) |\n| **Hits**        | Display search results with customizable item templates | [Docs](docs/components/Hits.md)        |\n| **Pagination**  | Navigate through search results                         | [Docs](docs/components/Pagination.md)  |\n\n#### Facet Components\n\n| Component          | Description                                   | Documentation                                   |\n|--------------------|-----------------------------------------------|-------------------------------------------------|\n| **RefinementList** | Checkbox/radio list for categorical filtering | [Docs](docs/components/Facet/RefinementList.md) |\n| **RangeInput**     | Min/max input fields for numeric ranges       | [Docs](docs/components/Facet/RangeInput.md)     |\n| **RangeSlider**    | Slider for numeric range filtering            | [Docs](docs/components/Facet/RangeSlider.md)    |\n\n#### Utility Components\n\n| Component              | Description                                | Documentation                                 |\n|------------------------|--------------------------------------------|-----------------------------------------------|\n| **CurrentRefinements** | Display active filters with remove buttons | [Docs](docs/components/CurrentRefinements.md) |\n| **ClearRefinements**   | Button to clear all active filters         | [Docs](docs/components/ClearRefinements.md)   |\n| **SortBy**             | Dropdown to change sort order              | [Docs](docs/components/SortBy.md)             |\n| **TotalHits**          | Display total number of results            | [Docs](docs/components/TotalHits.md)          |\n\n### Overriding Templates\n\nYou can override any component template by creating a file in your app's `templates/` directory:\n\n```\ntemplates/\n└── components/\n    └── Mezcalito/\n        └── UxSearch/\n            ├── Layout.html.twig          # Override the main layout\n            ├── SearchInput.html.twig     # Override search input\n            ├── Hits.html.twig            # Override results display\n            └── Facet/\n                └── RefinementList.html.twig\n```\n\n### Custom Hit Template\n\nThe most common customization is the hit (result item) template. Override `Hits.html.twig`:\n\n```twig\n{# templates/components/Mezcalito/UxSearch/Hits.html.twig #}\n\u003cdiv {{ attributes }}\u003e\n    {% for hit in this.resultSet.hits %}\n        \u003carticle class=\"product-card\"\u003e\n            \u003cimg src=\"{{ hit.image }}\" alt=\"{{ hit.name }}\"\u003e\n            \u003ch3\u003e{{ hit.name }}\u003c/h3\u003e\n            \u003cp class=\"price\"\u003e{{ hit.price|format_currency('EUR') }}\u003c/p\u003e\n            \u003ca href=\"{{ path('product_show', {id: hit.id}) }}\"\u003eView details\u003c/a\u003e\n        \u003c/article\u003e\n    {% endfor %}\n\u003c/div\u003e\n```\n\n\n## Advanced Usage\n\n### Event System\n\nCustomize search behavior with event subscribers:\n\n```php\nuse Mezcalito\\UxSearchBundle\\Event\\PreSearchEvent;\nuse Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;\n\nclass SearchSubscriber implements EventSubscriberInterface\n{\n    public static function getSubscribedEvents(): array\n    {\n        return [\n            PreSearchEvent::class =\u003e 'onPreSearch',\n        ];\n    }\n\n    public function onPreSearch(PreSearchEvent $event): void\n    {\n        $query = $event-\u003egetQuery();\n        // Modify the query before search execution\n        $query-\u003eaddFilter('status', 'published');\n    }\n}\n```\n\n📖 **[Event system documentation](docs/usage/customize-your-search.md#event-subscribers)**\n\n### Multiple Search Configurations\n\nYou can have multiple search configurations in one application:\n\n```php\n// Product search with Algolia\n#[AsSearch(index: 'products', adapter: 'algolia')]\nclass ProductSearch extends AbstractSearch { }\n\n// Blog search with Meilisearch\n#[AsSearch(index: 'posts', adapter: 'meilisearch')]\nclass BlogSearch extends AbstractSearch { }\n\n// User search with Doctrine\n#[AsSearch(index: 'App\\Entity\\User', adapter: 'orm')]\nclass UserSearch extends AbstractSearch { }\n```\n\nEach search can have its own adapter, facets, and configuration.\n\n## Documentation\n\n### Getting Started\n- [Installation \u0026 Quick Start](#installation)\n- [Choosing an Adapter](#choosing-an-adapter)\n- [Customizing Your Search](#customizing-your-search)\n\n### Adapters\n- [Algolia Configuration](docs/usage/algolia.md)\n- [Meilisearch Configuration](docs/usage/meilisearch.md)\n- [Doctrine Configuration](docs/usage/doctrine.md)\n- [Creating a Custom Adapter](docs/create-own-adapter.md)\n\n### Components\n- [Layout](docs/components/Layout.md) - Root wrapper\n- [SearchInput](docs/components/SearchInput.md) - Search box\n- [Hits](docs/components/Hits.md) - Results display\n- [Pagination](docs/components/Pagination.md) - Page navigation\n- [Facets](docs/components/) - All facet components\n- [View all components](docs/components/)\n\n### Advanced\n- [Customizing Your Search](docs/usage/customize-your-search.md) - Facets, sorting, events\n- [Component Customization](docs/components/) - Override templates and behavior\n\n## Contributing\n\nContributions are welcome! Here's how you can help:\n\n1. **Report bugs** - [Open an issue](https://github.com/mezcalito/ux-search/issues) with a clear description\n2. **Request features** - [Suggest new features](https://github.com/mezcalito/ux-search/issues) with use cases\n3. **Submit PRs** - Fork, create a feature branch, and submit a pull request\n4. **Improve docs** - Documentation improvements are always appreciated\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/mezcalito/ux-search.git\ncd ux-search\n\n# Start the Docker development environment\nmake up\n\n# Install dependencies\nmake install\n\n# Run tests\nmake test\n\n# Run code quality checks\nmake ci\n```\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/mezcalito/ux-search/issues)\n- **Discussions**: [GitHub Discussions](https://github.com/mezcalito/ux-search/discussions)\n- **Demo**: [Live Demo](https://ux-search.mezcalito.dev/demo)\n\n## License\n\nThis bundle is released under the [MIT License](LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmezcalito%2Fux-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmezcalito%2Fux-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmezcalito%2Fux-search/lists"}